Learn business/Java

[2편] 제네릭이란?


이번 챕터의 중요한 내용은 제네릭과 와일드 카드의 차이점이다. 이것 저것 많은 내용을 참고해서 정리해보았다.

 

제네릭과 상속에 대한 개념을 알고 아래 내용을 보도록 하자. 해당 글은 effective java의 “[ITEM 26] 로 타입은 사용하지 말라”와 이어지는 내용이다. 

 

제네릭 메소드 그리고 와일드 카드

제네릭 메소드는 클래스 전체가 아니라 하나의 메소드에 대해서만 제네릭 선언을 하고 싶을 때 사용도가 높다.

printList1 메소드가 제네릭 메소드이다. 리스트를 파라미터로 받아서 for 문을 돌려서 출력하는 기본적인 메소드이다. printList2 메소드는 제네릭 메소드는 아니고 일반 메소드이다. 다만, 와인드 카드로 매개변수화 된 List 콜렉션을 파라미터로 받고 있다.

 

사실 printList1과 printList2 메소드의 기능은 완전히 똑같다. 물론 컴파일이 되어서 내부적으로 돌아가는 것에 있어서는 다르겠지만 둘 중 어느 메소드를 사용하더라도 똑같은 결과를 얻을 수 있다. 그렇다면 두 메소드의 차이는 정말 없는 걸까?

 

참고) 잠깐만, 간단하지만 헷갈릴 수 있는 static 메소드와 제네릭

제네릭 클래스와 일반 클래스 내부에 선언된 메소드(method1, method2)가 있다. 두 코드 중에 컴파일 에러가 발생하는 곳이 있는데 어딜까?

 

바로 method1번 이다.
왜 그럴까? 그건 static이 갖는 특징과 타입이 결정되는 시점을 잘 생각해보면 알 수 있다.

위 코드에서 GenericClass의 제네릭 타입은 인스턴스가 생성될 때 결정이 된다. 하지만 static은 인스턴스 생성과 별도로 메모리에 올라가 있다. 그런데 그런 static으로 선언된 메소드에 인스턴스가 생성되는 시점에 결정되는 제네릭 타입을 매개변수로 받을 수는 없을 것이다. 반면에 제네릭으로 시그니처된 메소드는 호출되는 시점에 타입이 결정되기 때문에 컴파일 에러가 발생하지 않는 것이다.

 

다시, 제네릭과 와일드 카드 무슨 차이야?

제네릭과 와일드 카드의 차이를 이해하기 앞서 개념을 조금 더 확실하게 집고 넘어 가자.

General MethodGeneric Method가 있다. 이 둘의 차이점은 무엇일까? 파라미터를 받는 쪽을 조금 더 유심하게 보도록 하자.

1번은 Box<Object> 타입을 파라미터로 2번은 Box<T> 타입을 파라미터로 받는다. 얼핏 보면 두 메소드 모두 Box의 어떠한 타입이 전달되던 간에 잘 돌아갈 것 같은 생각이 든다. (왜냐면 Object이니까...)

 

결론은 아니다!

 

이전 포스팅과 관련이 있는 내용이 여기서 나온다. 바로 상속의 개념이 들어가는데, 위 메소드를 호출하는 쪽에서 Box<String> 혹은 Box<Integer>를 넘기고 싶다. 이때 2번 제네릭 메소드에 넘겨야 정상적으로 컴파일이 된다. Box<Object>Box<String>은 전혀 다른 파라미터화 타입이며, Box<Object>와 Box<Integer>는 전혀 다른 파라미터화 타입이기 때문이다. 즉, Box<Object>와 Box<String> 간의상속관계가 성립하지 않는 것이고, Box<Object>와 Box<Integer> 간의상속관계가 성립하지 않는 것이다.

그렇다면 Box<?>인 경우에는 어떨까? 당연히 제네릭 메소드처럼 Box<Stirng>와 Box<Integer> 파라미터화 타입을 넘길 수 있다. 그럼 기능이 똑같은데 자바는 왜 이렇게 두 가지를 나눠서 놓은 것일까? 자세한 메커니즘은 조금 더 공부를 해야겠지만 ‘토비’님의 권위에 기대어 차이점을 말하고자 한다.

 

제네릭 : 지금은 이 타입을 모르지만, 이 타입이 정해지면 그 타입 특성에 맞게 사용하겠다!
와일드 카드 : 지금도 이 타입을 모르고, 앞으로도 모를 것이다!

기능면에서는 완전히 똑같기 때문에 이왕이면 보기에 조금 더 간결한 와일드 카드를 사용하도록 하자. 메소드의 정의가 복잡할 수록 보기 어려운 법이니까. 사실, 위 차이점 이외에도 와일드 카드의 용도는 더 있다. 제네릭과 합쳤을 때 와일드 카드의 존재는 빛을 본다. 이 부분은 제한된 와일드 카드에 대해서 알아 본 뒤에 다시 알아보자.

'Learn business > Java' 카테고리의 다른 글

자바 클래스패스  (1) 2020.03.31
[5편] 제네릭이란?  (3) 2020.01.05
[4편] 제네릭이란?  (1) 2020.01.05
[3편] 제네릭이란?  (1) 2019.11.02
[1편] 제네릭이란?  (0) 2019.10.31