Tôi đã lớp sau:Có phải làm cho kiểu trả về chung với cùng một nhị phân xóa tương thích không?
public abstract Foo {
Foo() {}
public abstract Foo doSomething();
public static Foo create() {
return new SomePrivateSubclassOfFoo();
}
}
Tôi muốn thay đổi nó để định nghĩa sau đây:
public abstract Foo<T extends Foo<T>> {
Foo() {}
public abstract T doSomething();
public static Foo<?> create() {
return new SomePrivateSubclassOfFoo();
}
}
là sự thay đổi này nhị phân tương thích? I.e., mã sẽ được biên dịch dựa vào phiên bản cũ của lớp học có hoạt động với phiên bản mới mà không cần biên dịch lại không?
Tôi biết rằng tôi cần thay đổi SomePrivateSubclassOfFoo
, điều này là ok. Tôi cũng biết rằng thay đổi này sẽ kích hoạt cảnh báo về các loại thô khi mã máy khách cũ được biên dịch, điều này cũng tốt cho tôi. Tôi chỉ muốn đảm bảo rằng mã khách hàng cũ không cần phải được biên dịch lại.
Từ sự hiểu biết của tôi, điều này sẽ là ok vì việc xóa của T
là Foo
và do đó chữ ký của doSomething
trong mã byte giống như trước đây. Nếu tôi nhìn vào các chữ ký kiểu nội bộ được in bởi javap -s
, tôi thực sự thấy điều này được xác nhận (mặc dù chữ ký loại "không phải nội bộ" được in mà không cần -s
khác nhau). Tôi cũng đã thử nghiệm điều này, và nó đã làm việc cho tôi.
Tuy nhiên, Java API Compliance Checker cho tôi biết rằng hai phiên bản không tương thích nhị phân.
Vậy điều gì là chính xác? Liệu JLS có đảm bảo tính tương thích nhị phân ở đây hay chỉ là may mắn trong các thử nghiệm của tôi? (Tại sao điều này có thể xảy ra?)