서브 타이핑은 매개 변수화 된 유형에 대해 변하지 않습니다 . 클래스 Dog
가 하위 유형 인 Animal
경우에도 매개 변수화 된 유형 List<Dog>
은 하위 유형 이 아닙니다 List<Animal>
. 반대로 공변량 하위 유형 지정은 배열에서 사용되므로 배열 유형 Dog[]
은의 하위 유형입니다 Animal[]
.
변하지 않는 서브 타이핑은 Java에 의해 시행되는 유형 제약 조건이 위반되지 않도록합니다. @Jon Skeet이 제공 한 다음 코드를 고려하십시오.
List<Dog> dogs = new ArrayList<Dog>(1);
List<Animal> animals = dogs;
animals.add(new Cat()); // compile-time error
Dog dog = dogs.get(0);
@Jon Skeet이 말했듯 이이 코드는 불법입니다. 그렇지 않으면 개가 예상했을 때 고양이를 반환하여 유형 제약 조건을 위반하기 때문입니다.
위의 배열과 비슷한 코드를 비교하는 것이 좋습니다.
Dog[] dogs = new Dog[1];
Object[] animals = dogs;
animals[0] = new Cat(); // run-time error
Dog dog = dogs[0];
코드는 합법적입니다. 그러나 배열 저장소 예외가 발생 합니다. JVM은 공변량 서브 타이핑의 유형 안전성을 강제 할 수있는 방식으로 런타임에 해당 유형을 전달합니다.
이를 이해하기 위해 javap
아래 클래스에서 생성 한 바이트 코드를 살펴 보겠습니다 .
import java.util.ArrayList;
import java.util.List;
public class Demonstration {
public void normal() {
List normal = new ArrayList(1);
normal.add("lorem ipsum");
}
public void parameterized() {
List<String> parameterized = new ArrayList<>(1);
parameterized.add("lorem ipsum");
}
}
command를 사용하면 javap -c Demonstration
다음 Java 바이트 코드가 표시됩니다.
Compiled from "Demonstration.java"
public class Demonstration {
public Demonstration();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public void normal();
Code:
0: new #2 // class java/util/ArrayList
3: dup
4: iconst_1
5: invokespecial #3 // Method java/util/ArrayList."<init>":(I)V
8: astore_1
9: aload_1
10: ldc #4 // String lorem ipsum
12: invokeinterface #5, 2 // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
17: pop
18: return
public void parameterized();
Code:
0: new #2 // class java/util/ArrayList
3: dup
4: iconst_1
5: invokespecial #3 // Method java/util/ArrayList."<init>":(I)V
8: astore_1
9: aload_1
10: ldc #4 // String lorem ipsum
12: invokeinterface #5, 2 // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
17: pop
18: return
}
번역 된 메소드 본문의 코드가 동일한 지 확인하십시오. 컴파일러는 각 매개 변수화 된 유형을 삭제 로 대체했습니다 . 이 속성은 이전 버전과의 호환성을 손상시키지 않았다는 의미입니다.
결론적으로 컴파일러는 각 매개 변수화 된 유형을 삭제로 대체하기 때문에 매개 변수화 된 유형에는 런타임 안전성이 불가능합니다. 이것은 매개 변수화 된 유형을 구문 설탕에 지나지 않습니다.