Thực hiện phương pháp chung của Il Ilalal: Tại sao tôi không nhận được bất kỳ lỗi biên dịch nào?


8

Tôi đã có một giao diện chứa một phương thức có chữ ký này:

<P extends MergeProperty<T> & RestartApplicant> List<P> loadPropertiesFrom(T p1, T p2);

Về cơ bản, MergePropertylà một lớp KHÔNG thực hiện RestartApplicantRestartApplicantlà một giao diện chức năng có chứa một phương thức không thực sự quan trọng đối với sự hiểu biết về vấn đề này.

Đây là bắt. Khi tôi tạo một lớp thực hiện giao diện này, Java cho phép tôi chạy mà không gặp lỗi biên dịch mã sau:

public class MyImplementation implements MyInterfacePreviouslyDescribed {

    @Override
    public List<MergeProperty<MathObject>> loadPropertiesFrom(MathObject p1, MathObject p2) {
        return Arrays.asList(
            // some random instances of MergeProperty that do not implement RestartApplicant
        );
    }
}

Rõ ràng, tôi không tôn trọng các hạn chế của việc thực hiện ở đó. Với chữ ký này, danh sách tôi trở lại sử dụng Arrays.asList(...)không KHÔNG cần phải chứa các thành phần mà thực hiện RestartApplicant. Hãy nhớ rằng, MergePropertykhông thực hiện RestartApplicant. Vì vậy, điều này rất có thể sẽ kết thúc gây ra một số lỗi đúc ở đâu đó.

Tuy nhiên, tôi nhận được một cảnh báo:

Type safety: The return type List<Main.MergeProperty<Main.MathObject>> for
loadPropertiesFrom(Main.MathObject, Main.MathObject) (...) needs unchecked
conversion to conform to List<Main.MergeProperty&Main.RestartApplicant> from the
type Main.Test<Main.MathObject>

Câu hỏi của tôi là: tại sao tôi chỉ nhận được một cảnh báo? Dường như với tôi rằng tôi không thể biên dịch mã của mình. Có bất kỳ lý do cụ thể cho điều đó?

Cảm ơn trước.

BIÊN TẬP

Sau khi chơi một chút với mã của tôi, tôi nhận ra rằng nếu tôi chuyển "tuyên bố chung chung" sang cấp độ lớp, điều này sẽ dẫn đến:

interface MyInterfacePreviouslyDescribed<T, P extends MergeProperty<T> & RestartApplicant>

Thay vì chỉ

interface MyInterfacePreviouslyDescribed<T>

và rõ ràng

List<P> loadPropertiesFrom(T p1, T p2);

thay vì

<P extends MergeProperty<T> & RestartApplicant> List<P> loadPropertiesFrom(T p1, T p2);

sau đó tôi thực sự gặp lỗi biên dịch nếu tôi thử thực hiện "bất hợp pháp" như trước. Có vẻ còn lạ hơn ...

Câu trả lời:


2

Bạn thậm chí có thể làm:

    @Override
    public List<String> loadPropertiesFrom(MathObject p1, MathObject p2) {
        return Arrays.asList(
            // some random instances of MergeProperty that do not implement RestartApplicant
        );
    }

Trong trường hợp đầu tiên. Điều này là do phương thức ghi đè không chung chung và sẽ xóa được những thứ này List. Tại sao điều này được cho phép? Tôi thực sự không biết, có thể là một cái gì đó để làm với khả năng tương thích ngược.

Trong ví dụ thứ hai của bạn, có vẻ như nó thực sự phải là:

interface MyInterfacePreviouslyDescribed<T, P extends MergeProperty<T> & RestartApplicant> {

và trong quá trình thực hiện, bạn buộc các loại phải chính xác. Trên thực tế, ví dụ thứ hai là ví dụ trực quan - vì nó không biên dịch; và đó dự kiến. Mặt khác, thứ nhất phụ thuộc vào một số quy tắc tương thích cho các phương thức không chung chung cho phép ghi đè lên cùng một thao tác xóa.


Hấp dẫn. Ví dụ thứ hai có vẻ thực sự trực quan hơn sau tất cả. Và vâng, chữ "T" bị thiếu ở phần sau là lỗi đánh máy
Akami
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.