나는 최근에 Why doesn't Java 5+ API take advantage of covariant return types?을 만났습니다.복제본의 공변 반환 형식을 사용하면 호환성이 깨지겠습니까?
나는 우리가
ArrayList<String> list = new ArrayList<String>();
ArrayList<String> clone = list.clone();
대신
ArrayList<String> clone = (ArrayList<String>)list.clone();
하지만 일부에서 쓸 수있는 자바 5 JDK 개발자가 복제에 대한 공변 반환 형식을 사용하고 기존의 클래스를 변경 수, 질문에 동의 이유는 그렇게하지 않았습니다.
"이전에 컴파일 된 클래스가 새 반환 형식을 사용하여 메서드를 찾을 수없는 경우"내 test.ArrayList.clone
반환 형식을 Object에서 ArrayList로 변경했지만 일부 문제가 재현되지 않았습니다. 바이트 코드에서, 오래된 test.ArrayList.clone
의 호출은 test.ArrayList.clone()Ltest.ArrayList
에의 서명을 변경
INVOKEVIRTUAL test.ArrayList.clone()Ljava/lang/Object;
는, 메소드 서명이 반환 유형이 포함처럼 보이는, 그래서 내 변경 후. 그래서 오래된 클래스가 깰 것으로 보인다,하지만 test.ArrayList.class
public clone()Ltest.ArrayList;
public bridge clone()Ljava/lang/Object;
2 복제 방법은 두 번째는 다리가 있기 때문에 사실은, 그것이 공변 버전을 호출하지 모든하지 않습니다
...
INVOKEVIRTUAL ArrayList.clone()Ltest.ArrayList;
...
그래서 오래된 클래스는 문제없이 계속 작동합니다.
클론의 리턴 타입 변경이 바이트 코드를 깨뜨릴 수있는 방법을 설명 할 수 있습니까? 링크 된 질문에
내가 이해하는 한 그것은 타입 소거 때문이다 : 런타임에,'ArrayList'은'X'에 대해'ArrayList'가된다. 그것은 1.5 이전 코드와의 호환성을위한 것입니다. –
fge