Generic 을 한 눈에 파악하기 위해 간단한 샘플 코드를 작성해 봄

 

public class Test {

	public static void main(String[] args) {
		MyClass<String> TisString = new MyClass<>("Hi!");
		System.out.println(TisString.getItem()); //Hi!
		
		MyClass<Integer> TisInteger = new MyClass<>(123);
		System.out.println(TisInteger.getItem()); //123
	}
}

class MyClass<T>{
//	static T staticItem; //T 는 static 멤버의 타입으로 넣을 수 없음
	T item;
	MyClass(T item){
		this.item = item;
	}
	T getItem() {
		return this.item;
	}
}

 

만약 MyClass 에 extends 를 통해 제한을 걸게된다면?

public class Test {

	public static void main(String[] args) {
		MyClass<String> TisString = new MyClass<>("Hi!");
		System.out.println(TisString.getItem()); //Hi!
		
		//Integer 는 String 의 자손이 아니기 때문에, 아래부터 컴파일 에러가 뜸 
		//MyClass<Integer> TisInteger = new MyClass<>(123);
		//System.out.println(TisInteger.getItem()); //123
	}
}

class MyClass<T extends String>{
	T item;
	MyClass(T item){
		this.item = item;
	}
	T getItem() {
		return this.item;
	}
}

 

 

Generic Class 를 파라미터로 갖는 메소드를 사용하려면 다음과 같이 가능하지만

String, Integer 외에 다른 타입, 이를테면 Character, Long 등의 타입을 받으려면 printT3, printT4.... 를 더 만들어야 함

 

public class Test {

	public static void main(String[] args) {
		MyClass<String> TisString = new MyClass<>("Hi!");
		printT1(TisString);
		
		MyClass<Integer> TisInteger = new MyClass<>(123);
		printT2(TisInteger);
	}
	
	static void printT1(MyClass<String> myClass) {
		System.out.println(myClass.getItem());
	}

	static void printT2(MyClass<Integer> myClass) {
		System.out.println(myClass.getItem());
	}
    
    //필요하면 더 만들어야 함..
}

class MyClass<T>{
	T item;
	MyClass(T item){
		this.item = item;
	}
	T getItem() {
		return this.item;
	}
}

 

따라서 메소드에 Wildcard 를 사용하여 모든 타입을 받아줄 수 있도록 함

여기서 static 의 유무는 Generic 과는 상관 없음

public class Test {

	public static void main(String[] args) {
		MyClass<String> TisString = new MyClass<>("Hi!");
		printT(TisString);
		
		MyClass<Integer> TisInteger = new MyClass<>(123);
		printT(TisInteger);
	}
	
	static void printT(MyClass<?> myClass) {
		System.out.println(myClass.getItem());
	}
}

class MyClass<T>{
	T item;
	MyClass(T item){
		this.item = item;
	}
	T getItem() {
		return this.item;
	}
}

혹은 다음과 같이 Generic Method 를 만들면, Method 에 Generic 을 넣을 수 있다.

public class Test {

	public static void main(String[] args) {
		MyClass<String> TisString = new MyClass<>("Hi!");
		printT(TisString);
		
		MyClass<Integer> TisInteger = new MyClass<>(123);
		printT(TisInteger);
	}
	
	static <T> void printT(MyClass<T> myClass) {
		System.out.println(myClass.getItem());
	}
}

class MyClass<T>{
	T item;
	MyClass(T item){
		this.item = item;
	}
	T getItem() {
		return this.item;
	}
}

 

WildCard 랑 Generic Method 랑 무슨 차인지 모르겠음

WildCard 에만 상한/하한 제한을 줄 수 있다는 것 외에는...

 

Generic 타입은 컴파일러에 의해 모두 제거된다.

예를 들어, Generic 이 아름답게 수놓아진 코드를 컴파일한다고 하자.

이 코드 내의 Generic 은 컴파일러에 의해 String, MyClass, Integer ,,,, 등으로 바뀐다.

그래서 그 결과물(.class 파일) 내에서 Generic (T) 은 없다.

 

 

 

+ Recent posts