자바 제네릭 정리 노트

<?>   같다 <? extends Object>

PECS (Produce Extends Consumer Super)

  • 제공자(in / read)

    <? extends T>
    
  • 소비자(out / write)

    <? super T>
    

제네릭 List와 List은 공변이 아니다.

  • 공변이란 자기 자신과 자식 인스턴스만 수용할 수 있다는 뜻

  • 반공변 : 자기 자신과 부모만 허용
  • 무공변 : 오로지 자신

제네릭은 무공변이다.

상속 관계로 보면 Object는 String에 상위 타입이기 때문에

List strList = Arrays.asList("aa", "bb");

List objList = strList; 가 될 것 같은데. 제네릭은 무공변이기에 오류다.

제네릭에서도 상속 개념과 같이 유연하게 처리하기 위해

<? extends T>, <? super T> 통해 처리   있다. 

, 공변 : <? extends T> / 반공변 : <? super T> 이다. 

제네릭은 컴파일 타임시에 타입 안전을 보장하기 위해 타입이 명시되어 있어. 타입 매칭이 틀리면 오류를 통해 개발자가 컴파일 단에서 확인할 수 있다.

런타임에서는 타입이 소거되어 List은 => List 의 형태 RawType이 된다.

자바에 제네릭 등장이 늦었기 때문에. 기존에 기능들을 호환하기 위해서 어쩔 수 없이. RawType을 수용한 상태라고 보면 되는데. (RawType은 런타임 도중 타입 안전을 보장 할 수 없다. 제네릭이 탄생하게된 원인 이라고 볼 수 있다) 제네릭이라는 기능을 통해 컴파일 단에서 타입 안전을 보장하게 되면. 런타임시 타입이 소거되어도. 타임에 의해 오류가 발생할 일이 없어 지기 때문이다. 보장되는 이유는 당연하게도 컴파일 단에서 타입 매칭 문법 오류가 발생하면 컴파일 자체가 안되기 때문에.