나는 한 다음 클래스 :동일한 이진 바이너리를 사용하는 리턴 유형 일반이 호환 가능합니까?
public abstract Foo {
Foo() {}
public abstract Foo doSomething();
public static Foo create() {
return new SomePrivateSubclassOfFoo();
}
}
나는 다음과 같은 정의로 변경하려면 :이 변경 바이너리 호환
public abstract Foo<T extends Foo<T>> {
Foo() {}
public abstract T doSomething();
public static Foo<?> create() {
return new SomePrivateSubclassOfFoo();
}
}
인가? 즉, reocmpilation하지 않고 이전 버전의 클래스에서 컴파일 된 코드가 새 버전에서 작동합니까?
SomePrivateSubclassOfFoo
을 변경해야한다는 것을 알고 있습니다. 괜찮습니다. 또한 오래된 클라이언트 코드가 컴파일 될 때이 변경으로 인해 원시 형식에 대한 경고가 표시된다는 것을 알고 있습니다. 이는 나에게도 좋습니다. 난 그냥 오래된 클라이언트 코드를 다시 컴파일 할 필요가 있는지 확인하고 싶습니다.
T
의 지우기가 Foo
이고 따라서 바이트 코드에서 doSomething
의 서명이 이전과 동일하기 때문에이 내용을 확인해야합니다. javap -s
에 의해 인쇄 된 내부 형식 서명을 보면 실제로 확인 된 것을 볼 수 있습니다 (-s
없이 인쇄 된 "비 내부"형식의 서명은 다르지만). 나는 이것을 시험해 보았고 그것은 나를 위해 일했다.
그러나 Java API Compliance Checker은이 두 버전이 바이너리 호환되지 않는다고 알려줍니다.
그래서 무엇이 맞습니까? JLS는 여기서 바이너리 호환성을 보증합니까, 아니면 테스트에서 운이 좋았습니까? (왜 이런 일이 일어날 수 있겠습니까?)