Covariant, Contravariant, Invariant에 대하여

지니🧸·2024년 7월 23일
0

Java

목록 보기
17/23

형 변환에 대해 파고들면 Covariant, Contravariant, Invariant과 같은 용어들을 쉽게 만날 수 있다.

세 용어 모두 형 변환에 있어 슈퍼타입-서브타입 관계성을 정의한다.

AB를 타입, f를 형 변환, 그리고 <=을 서브타입 관계성이라 가정하자. (즉, A<=BAB의 서브타입을 의미한다)

  • A<=B일 때 f(A) <= f(B)Covariant
  • A<=B일 때 f(B) <= f(A)Contravariant
  • 위 두가지 상황에 모두 해당하지 않으면 Invariant

f(A) = List<A>로 다시 확인해보자

  • CovariantList<String>List<Object>의 서브타입임을 의미한다.
  • ContravariantList<Object>List<String>의 서브타입임을 의미한다.
  • InvariantList<String>List<Object>는 서로 변환되지 않는, StringObject간 서브 타입 관계성이 사라짐을 의미한다.

Covariant

Java에서f(A) = A[]Covariant하다. 즉, String[]Object[]의 서브타입에 해당한다.

Invariant와 Wildcard

Java에서는 List<String>List<Object>Invariant하다. Generics 자체가 invariant로 인정되는 경우가 많다.

또 예를 들자면, IntegerNumber의 서브 타입이지만, List<Integer>List<Number>의 서브 타입이 아니다. 이 둘의 공통 부모는 List<?> 뿐이다.


출처: 오라클 공식 문서

그래서 Invariant 관계에 놓인 이 두 리스트에 대해 관계성을 형성하기 위해서는 와일드카드를 사용해야 한다.

List<? extends Integer> intList = new ArrayList<>();
List<? extends Number>  numList = intList;  

List<? extends Number> numListNumber의 서브타입 (Integer도 해당)의 리스트를 모두 허용하기 때문에 numListintList를 지정할 수 있다.


https://stackoverflow.com/questions/8481301/covariance-invariance-and-contravariance-explained-in-plain-english
https://docs.oracle.com/javase/tutorial/java/generics/subtyping.html

profile
우당탕탕

0개의 댓글