2016-07-08 15 views
5

Tôi gặp phải sự cố lạ trong dự án của mình. Bây giờ tôi đã đơn giản hóa vấn đề và viết một ví dụ nhỏ ở đây để minh họa cho sự nhầm lẫn của tôi:Điều gì xảy ra với từ khóa "siêu" trong loại Java chung

public class Question { 
    class Q1 {} 

    class Q2 extends Q1 {} 

    interface In<T> { 
     void f(T t); 
    } 

    List<Q2> list; 

    void f(In<? super List<? super Q2>> in) { 
     in.f(list); 
    } 

    static void g() { 
     Question question = new Question(); 
     In<Collection<Q1>> in1 = new In<Collection<Q1>>() { 
      @Override 
      public void f(Collection<Q1> o) {} 
     }; 
     In<List<Q2>> in2 = new In<List<Q2>>() { 
      @Override 
      public void f(List<Q2> o) {} 
     }; 
     question.f(in1); //Error! 
     question.f(in2); //Error! 
    } 
} 

Mục tiêu của tôi là làm cho phương pháp này f(In<? super List<? super Q2>>) linh hoạt hơn. Tôi có thể vượt qua in1 hoặc in2 cho phương pháp. Nhưng không thể vượt qua được! Chuyện gì thế?

Có thể this answer sẽ có ý nghĩa. Nhưng câu hỏi của tôi thì khác !!! Loại chung của tôi là In<? super List<? super Q2>>, loại chung trong một loại chung.

+0

@AndyTurner "mọi thứ phù hợp? Siêu Q2" vậy tại sao 'question.f (in1)' là lỗi? bạn có thể rõ ràng hơn không? – Jerry06

+0

@ Jerry06 Tôi nghĩ tôi đã hiểu sai câu hỏi. Đã mở lại. –

Trả lời

0
In<Collection<? extends Q1>> in1 = new In<Collection<? extends Q1>>() { 
      @Override 
      public void f(Collection<? extends Q1> o) {} 
     }; 
     In<List<? extends Q2>> in2 = new In<List<? extends Q2>>() { 
      @Override 
      public void f(List<? extends Q2> o) {} 
     }; 
+0

'extend' là khác nhau. Nó dễ hơn. Hãy thay đổi nó thành 'super' và xem điều gì xảy ra. –

+0

có. Lỗi tương tự với siêu – Gangadhar

2

Một loại generic của mẫu A<? extends B> nghĩa là ? có thể được thay thế bằng B hoặc bất kỳ siêu loại B. Do đó, List<? super Q2> có nghĩa là: List<Object>, List<Q1> hoặc List<Q2>.

Mặc dù Q1 là siêu loại Q2, List<Q1> không phải là siêu kiểu List<Q2>. Điều này có nghĩa là loại siêu phổ biến duy nhất của List<Object>, List<Q1>List<Q2>Object. Vì vậy, điều duy nhất bạn có thể chuyển sang phương thức fIn<Object>.

Cách bạn cần giải quyết điều này phụ thuộc vào sự linh hoạt bạn thực sự cần: loại đối tượng nào bạn muốn chuyển đến f và bạn muốn làm gì với các đối tượng đó?

+0

Còn về '> '? Và tôi nên làm gì nếu tôi muốn chuyển mọi lớp con của 'Bộ sưu tập' sang' f'? –

Các vấn đề liên quan