hgk0404
hgk0404.tistory
hgk0404

공지사항

전체 방문자
오늘
어제
  • 전체 카테고리 N
    • [컴퓨터비전] N
    • [Computer Science]
      • [컴퓨터네트워크]
      • [알고리즘]
      • [자료구조 in C]
      • [C & C++]
      • [이산수학]
      • [Math]
    • [머신러닝]
      • [Numpy, Pandas]
    • [Cloud]
      • [AWS]
      • [NCP]
      • [Kubernetes]
      • [Terraform]
    • [Dev]
      • [가상환경]
      • [Linux]
      • [Docker]
    • [Python]
    • [Coding Test]
      • [백준]
      • [프로그래머스]
      • [SQL]
    • [WEB]
    • [자격증, 일상]
    • [엑셀]
    • [금융]

인기 글

최근 글

최근 댓글

250x250
hELLO · Designed By 정상우.
hgk0404

hgk0404.tistory

[WEB]

[Java] 자바 제네릭 클래스, 제네릭 메소드

2022. 9. 24. 00:27
728x90

제네릭이 갖는 의미는 '일반화'이며 그 대상은 자료형입니다.

 

ArrayList, LinkedList 등을 생성할 때 "객체<타입> 객체명 = new 객체<타입>();" 의 방식으로 사용되었습니다.

ArrayList<Integer> list1 = new ArrayList<Integer>();
ArrayList<String> list2 = new ArrayList<Integer>();

LinkedList<Double> list3 = new LinkedList<Double>():
LinkedList<Character> list4 = new LinkedList<Character>();

제네릭도 이와 같이 <>안에 타입을 지정해 줍니다.

 

하지만, 위와 같이 한가지 타입만을 지원하는 자료구조를 만들고 싶지 않고 여러가지 타입을 지원하는 자료구조를 만들고 싶을떄 제네릭을 사용할 수 있습니다. 제네릭은 클래스 내부에서 지정하는 것이 아닌 외부에서 사용자에 의해 지정되는 것을 의미합니다. 자바에서 제네릭이 등장한 이후로 자료형에 의존적이지 않은 클래스를 작성할 수 있게 되었습니다.

 

제네릭은 원시 타입(primitive type)이 아닌 참조 타입(reference type)으로 사용해야 합니다.

 

1. 클래스 및 인터페이스 선언

public class ClassName <T> { ... }
public Interface InterfaceName <T> { ... }

 

기본적인 제네릭 타입의 클래스나 인터페이스의 경우 다음과 같이 선언합니다.

T타입은 해당 블록 {...}에서만 유효합니다.

 

예시)

public class ClassName <T, K> { ... }
 
public class Main {
	public static void main(String[] args) {
		ClassName<String, Integer> a = new ClassName<String, Integer>();
	}
}

 

예시에서는 T는 String이 되고 K는 Interger가 됩니다.

제네릭은 타입을 지정할때 원시타입(primitive type)이 아닌 참조 타입(reference type)으로 선언해야합니다. 즉, int, double, char같은 타입은 올 수 없고 Interger, Double, String등으로 사용할 수 있습니다.

 

그리고 참조타입이 올 수 있다는것은 클래스나 인터페이스도 타입으로 올 수 있다는 것입니다.

 

public class ClassName <T> { ... }
 
public class Student { ... }
 
public class Main {
	public static void main(String[] args) {
		ClassName<Student> a = new ClassName<Student>();
	}
}

 

2. 제네릭 클래스

제네릭 클래스 선언

// 제네릭 클래스
class ClassName<E> {
	private E element;	// 제네릭 타입 변수
	void set(E element) {	// 제네릭 파라미터 메소드
		this.element = element;
	}
	E get() {	// 제네릭 타입 반환 메소드
		return element;
	}
}
class prac2 {
	public static void main(String[] args) {
		ClassName<String> a = new ClassName<String>();
		ClassName<Integer> b = new ClassName<Integer>();
		a.set("10");
		b.set(10);
		System.out.println("a data : " + a.get());
		// 반환된 변수의 타입 출력 
		System.out.println("a E Type : " + a.get().getClass().getName());
		System.out.println();
		System.out.println("b data : " + b.get());
		// 반환된 변수의 타입 출력 
		System.out.println("b E Type : " + b.get().getClass().getName());
	}
}

ClassName이란 객체를 생성할때 <>안에 타입 파라미터(type parameter)를 지정합니다.

a객체의 ClassName의 제너릭 타입은 String으로 모두 변환되고, b객체의 ClassName의 제너릭 타입은 Integer로 모두 변환됩니다.

 

결과)

a data : 10
a E Type : java.lang.String

b data : 10
b E Type : java.lang.Integer

 

예시- 값을 2개 사용할 때)

// 제네릭 클래스 
class ClassName<K, V> {	
	private K first;	// K 타입(제네릭)
	private V second;	// V 타입(제네릭) 
	
	void set(K first, V second) {
		this.first = first;
		this.second = second;
	}
	K getFirst() {
		return first;
	}
	V getSecond() {
		return second;
	}
}
 
// 메인 클래스 
class prac2 {
	public static void main(String[] args) {
		ClassName<String, Integer> a = new ClassName<String, Integer>();
		a.set("10", 10);
		System.out.println("  fisrt data : " + a.getFirst());
		// 반환된 변수의 타입 출력 
		System.out.println("  K Type : " + a.getFirst().getClass().getName());
		System.out.println("  second data : " + a.getSecond());
		// 반환된 변수의 타입 출력 
		System.out.println("  V Type : " + a.getSecond().getClass().getName());
	}
}

이렇게 외부 클래스에서 제네릭 클래스를 생성할때 <>안에 타입을 파라미터로 보내서 제네릭 타입을 지정해 줄 수 있습니다.

 

결과)

  fisrt data : 10
  K Type : java.lang.String
  second data : 10
  V Type : java.lang.Integer

 

3. 제네릭 메소드

클래스에서 이름 옆에 <T>등을 붙여 제네릭 타입을 설정하여 클래스 내에서 사용할 수 있었는데 클래스가 아닌 단일 메소드에만 한정된 제네릭도 사용할 수 있습니다.

 

제네릭 메소드는 제네릭 클래스에서 지정한 제네릭 유형과 다른 독립적인 제네릭 유형을 가질 수 있습니다.

 

기본적인 형식은 다음과 같습니다.

public <T> T genericMethod(T o) {	// 제네릭 메소드
		...
}
 
[접근 제어자] <제네릭타입> [반환타입] [메소드명]([제네릭타입] [파라미터]) {
	// 텍스트
}

 

예시)

// 제네릭 클래스
class ClassName<E> {
	private E element;	// 제네릭 타입 변수
	void set(E element) {	// 제네릭 파라미터 메소드
		this.element = element;
	}
	E get() {	// 제네릭 타입 반환 메소드 
		return element;
	}
	<T> T genericMethod(T o) {	// 제네릭 메소드
		return o;
	}
}

public class prac2 {
	public static void main(String[] args) {
		ClassName<String> a = new ClassName<String>();
		ClassName<Integer> b = new ClassName<Integer>();
		a.set("10");
		b.set(10);
		System.out.println("a data : " + a.get());
		// 반환된 변수의 타입 출력 
		System.out.println("a E Type : " + a.get().getClass().getName());
		System.out.println();
		System.out.println("b data : " + b.get());
		// 반환된 변수의 타입 출력 
		System.out.println("b E Type : " + b.get().getClass().getName());
		System.out.println();
		// 제네릭 메소드 Integer
		System.out.println("<T> returnType : " + a.genericMethod(3).getClass().getName());
		// 제네릭 메소드 String
		System.out.println("<T> returnType : " + a.genericMethod("ABCD").getClass().getName());
		// 제네릭 메소드 ClassName b
		System.out.println("<T> returnType : " + a.genericMethod(b).getClass().getName());
	}
}

 

예시)

a data : 10
a E Type : java.lang.String

b data : 10
b E Type : java.lang.Integer

<T> returnType : java.lang.Integer
<T> returnType : java.lang.String
<T> returnType : ClassName

 

제네릭 메소드의 파라미터 타입에 따라 T타입이 정해집니다.

 

 


참고한 포스팅

 

 

728x90
저작자표시 동일조건

'[WEB]' 카테고리의 다른 글

[Java] 자바 컬렉션 2  (0) 2022.09.25
[Java] 자바 컬렉션  (0) 2022.09.24
[Java] Object 클래스  (0) 2022.09.23
[Java] 인터페이스와 추상 클래스  (0) 2022.09.23
[HTML & CSS] CSS 박스모델 관련 속성  (0) 2022.09.19
'[WEB]' 카테고리의 다른 글
  • [Java] 자바 컬렉션 2
  • [Java] 자바 컬렉션
  • [Java] Object 클래스
  • [Java] 인터페이스와 추상 클래스
hgk0404
hgk0404
공부기록

티스토리툴바