2013-01-15 46 views
8

thể trùng lặp:
What’s the difference between <?> and <? extends Object> in Java Generics?Danh sách <?> so với Danh sách <? extends Object>

tôi thấy rằng List<?>List<? extends Object> hành động theo cách tương tự. Đối với tôi, không có sự khác biệt giữa chúng. Nếu tôi không đúng, bạn có thể giải thích cho tôi sự khác biệt không?

import java.util.ArrayList; 
import java.util.List; 

public class TestClass { 

static void func1(List<?> o, Object s) { 
    o.add(null); // only null 
    o.add(s); // wrong 
    o.get(0); // OK 
} 

static void func2(List<? extends Object> o, Object s) { 
    o.add(null); // only null 
    o.add(s); // wrong 
    o.get(0); // OK 
} 

public static void main(String[] args) { 
    func1(new ArrayList<String>(), new Integer(1)); 
    func2(new ArrayList<String>(), new Integer(1)); 

    List<? extends Object> list1 = new ArrayList<Object>(); 
    List<?> list2 = new ArrayList<Object>(); 

    List<? extends Object> list3 = new ArrayList<String>(); 
    List<?> list4 = new ArrayList<String>(); 
} 
} 
+5

Không có sự khác biệt nào. 'extends Object' thừa và ngược lại, giống như viết' class F extends Object'. –

+1

Tôi sẽ đặt cược chúng tương đương, vì tất cả các lớp trong Java ngầm mở rộng 'Object'. – murgatroid99

+1

Không có sự khác biệt nào cả, đó là hậu quả của thiết kế/ngữ pháp ngôn ngữ. – nullpotent

Trả lời

1

Cả hai đều giống nhau bởi vì tất cả các đối tượng trong Java mở rộng Object. Tôi thích List<?> vì nó ngắn gọn hơn.

1

Tương tự như cách MyClass extends Object cho mỗi lớp List<? extends Object> giống với List<?>.

0

Mặc dù tôi là đạo văn Marko, mà tôi xin lỗi, nhận xét của anh ấy là câu trả lời đúng.

Không có sự khác biệt, bởi vì hoàn toàn mọi loại extends Object.

9

Đó là phức tạp ...

Đối với bất kỳ loại biến T, spec nói http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.4

Mỗi loại biến ... có một ràng buộc. Nếu không có ràng buộc nào được khai báo cho một biến kiểu, thì Object được giả định.

Người ta cũng nghĩ rằng đó cũng đúng với ký tự đại diện và ? chỉ là viết tắt của ? extends Object.

Tuy nhiên, tìm kiếm thông qua thông số kỹ thuật, không có bằng chứng nào cho thấy ký tự đại diện phải có giới hạn trên (hoặc giới hạn dưới). "Không giới hạn" ? được xử lý nhất quán rõ ràng từ các ký tự đại diện bị chặn.

Chúng ta có thể suy ra từ quy tắc subtyping, mà List<?>List<? extends Object> là tuýp phụ của nhau, ví dụ, họ cơ bản cùng loại. (Khoản khấu trừ tùy thuộc vào thực tế là E trong số interface List<E> có giới hạn trên bị ràng buộc Object; nhưng các quy tắc không yêu cầu giới hạn trên ký tự đại diện)

Tuy nhiên, đặc điểm xử lý hai cách khác nhau. Ví dụ http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.7List<?> là một loại reifiable, nhưng List<? extends Object> là không, có nghĩa là

// ok 
    List<?>[] xx = {}; 
    // fail 
    List<? extends Object>[] yy = {}; 

    // ok 
    boolean b1 = (y instanceof List<?>); 
    // fail 
    boolean b2 = (y instanceof List<? extends Object>); 

Tôi không hiểu tại sao mặc dù. Có vẻ như hoàn toàn tốt khi nói một ký tự đại diện phải có giới hạn trên và giới hạn dưới, mặc định là Objectnull type.

+0

Nhưng, có điều này 'Với một tuyên bố kiểu chung G , G tương tự như một số X <: B. G .' trong 4.5.1. – nullpotent

+0

@iccthedral - được áp dụng cho trường hợp 'Danh sách', 'Danh sách tương tự như Danh sách đối với một số X <: Object' – irreputable

+1

Vâng, vâng. Đó là quan điểm của tôi. 'X <: B' nên (?) Là một quan hệ kiểu con bao gồm, tuy nhiên tôi không thể tìm thấy tham chiếu cho điều này. Nó chỉ sau khi 'T mở rộng C' là bao gồm là tốt. – nullpotent

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