타입 시스템에서의 변성이란 타입이 변하는 성질을 띄는지에 대한 것으로
불변성, 공변성, 반공변성으로 표현한다
전달된 타입이 변하지 않는다
타입 불변성을 띄면 읽기와 쓰기 모두
타입을 안전하게 사용할 수 있다
설정한 타입이 타입 상한이 된다
상속 관계에서 구체적인 타입인 서브 타입을 일반적인 타입인 수퍼 타입에서도
안전하게 취급할 수 있는 경우
수퍼 타입을 사용하는 곳에서 서브 타입도 지원하는 것
공변성을 지원하는 경우
타입 매개변수 제한으로 설정한 타입과 하위 타입을 모두 받을 수 있고
설정 타입보다 하위 타입이 입력되더라도 상위 타입으로 다룬다
읽기 작업 시 타입을 안전하게 사용할 수 있다
<? extends Integer>
공변성은 해당 리스트가 Integer 를 생산할 수 있는 능력을 보장한다는 타입 경계를 설정하는 것으로 볼 수 있다
리스트에서 꺼낸 요소는 최소한 Integer 타입임을 보장한다
List<? extends Number>
는 List<Integer>
, List<Double>
등 Number
의 하위 타입 리스트를 참조할 수 있다
이는 자바의 객체 지향적 특성인 다형성 덕분이다
하위 타입의 객체는 상위 타입으로 참조될 수 있기 때문
설정한 타입이 타입 하한이 된다
상속 관계에서 수퍼 타입을 서브 타입에서도 안전하게 취급할 수 있는 경우
서브 타입을 사용하는 곳에서 수퍼 타입도 지원하는 것
반공변성을 지원하는 경우
제한으로 설정한 타입과 설정한 타입의 상위 타입을 모두 받을 수 있고
설정 타입보다 상위 타입으로 입력되더라도 설정 타입으로 다룬다
쓰기 작업 시 안전하게 추가할 수 있다
<? super Integer>
반공변성은 해당 리스트가 Integer 를 소비(사용)할 수 있는 능력을 보장한다는 타입 경계를 설정하는 것으로 볼 수 있다
List<? super Integer>
는 Integer
또는 Integer의 상위 타입(Number, Object)
을 담을 수 있는 리스트가 된다
리스트의 실제 타입은 Integer보다 더 일반적인 타입일 수 있지만
Integer를 처리하는 데는 문제가 없다는 것을 컴파일러에게 알려주는 것
제네릭은 타입 상한을 지정할 수 있지만
들어온 타입 그대로를 반환한다
public static <T extends Object> T genericMethod(T generic) {
return generic
}
위와 같은 제네릭 메서드의 제네릭 타입 T 가 있을 때
Integer result = GenericPractice.genericMethod(10);
Integer 타입을 인수로 전달하면
반환값 역시 Integer 가 된다
<T extends Object>
로 타입의 상한을 설정할 수는 있지만
입력된 타입이 변하지 않는다
와일드카드는 공변성과 반공변성을 지원한다
List<? extends Integer>
List<? super Integer>