API를 발전 시키려고합니다. 이 진화의 일부로 고급 클라이언트가 새 기능에 액세스 할 수 있도록 메소드의 리턴 유형을 서브 클래스 (전문화)로 변경해야합니다. 예 (추한을 무시 : 메소드의 반환 형식이의 서명의 일부이기 때문에자바 이진 호환성 - invokevirtual 의미를 사용하는 공변 반환 형식에 대한 제안 된 솔루션의 RFC
public interface ExtendedEntity extends Entity {
boolean b();
}
public interface Intf2 extends Intf1 {
ExtendedEntity entity();
}
public interface Main {
Intf2 intf();
}
그러나, 클라이언트가 이미 컴파일 :
public interface Entity {
boolean a();
}
public interface Intf1 {
Entity entity();
}
public interface Main {
Intf1 intf();
}
내가 지금 이런 ExtendedEntity, Intf2 및 홈페이지를 갖고 싶어 이전 버전의 코드는 링키지 오류를 보여줍니다 (메소드가 없습니다. iirc).
메인에 다른 리턴 유형으로 메소드를 추가하고 있습니다. 두 가지 메소드 하위 유형 반환) 동일한 구현 메소드 (서브 타입을 돌려 준다)에 맵됩니다. 주 - 내가 아는 한 JVM에서는 허용되지만 Java 스펙에서는 허용되지 않습니다.
내 솔루션은 이으로 보이고 필요한 인터페이스를 추가하기 위해 Java 클래스 시스템에 악용 (필자는 다른 말도 없음)이 있습니다.
public interface Main_Backward_Compatible {
Intf1 intf();
}
public interface Main extends Main_Backward_Compatible{
Intf2 intf();
}
이제 기존 고객은 (정확한 반환 형식과 방법은 유형 계층 구조에 존재하기 때문에) 올바른 방법은 invokevirtual 조회에 반환해야합니다 실제로 작동 구현은 하위 유형을 반환 하나가 될 것입니다 Intf2.
이 은 작동하려면입니다. 내가 고안 할 수있는 모든 테스트에서 (반사는 제외 -하지만 그 비트는 신경 쓰지 않는다) 은 일을했다.
항상 작동합니까? 내 추론 (invokevirtual에 대한)이 맞습니까?
또 다른 관련 질문 - "실제"바이너리 호환성을 확인하는 도구가 있습니까? 내가 찾은 유일한 방법은 각 메소드를 단독으로 살펴 보았지만 유형 계층 구조는 고려하지 않았습니다.
감사합니다.
란.
편집 - (계정 유형 계층 구조를 고려하지 않음) 내가 시도 "너무 좋지 않다"발견했습니다 도구 :
- Clirr 0.6.
- IntelliJ "APIComparator"플러그인.
편집 2 - 물론 내 클라이언트는 구현 클래스를 내 인터페이스 (서비스 생각) 작성에서 제외됩니다. 그러나 예제를 완성하려면 인터페이스 대신 추상 클래스 (Main의 경우)라고 생각하십시오.
이것은 한 단계 더 문제를 푸는 것입니다. Main (또는 Main2)을 어딘가에서 제공해야합니다. 이 모든 것을 상향식으로 전파 할 수는 있지만 사실은 엄청난 수의 인터페이스를 다루고 있으며 그 중 아무 것도 변경 (공장, 서비스, 공장, 서비스 등)과 관련이 없습니다. –
Intf1을 반환하도록 선언 된 메서드에서 Intf2. 기존 인터페이스의 수정을 피할 수 있습니다. –