2013-01-09 41 views
19

Tôi đã đọc về generics và tôi không hiểu sự cần thiết cho các ký tự đại diện không liên kết và cách nó khác với loại thô. Tôi đọc this question nhưng vẫn chưa hiểu rõ. Trong Java tutorial page for unbound wildcard tôi dưới hai điểm và tôi không hiểu điểm đầu tiên:Sự khác biệt giữa một ký tự đại diện không ràng buộc và một kiểu thô

  • Nếu bạn đang viết một phương pháp có thể được thực hiện sử dụng chức năng cung cấp trong lớp Object.
  • Khi mã đang sử dụng các phương thức trong lớp chung không phụ thuộc vào thông số loại. Ví dụ: List.size() hoặc List.clear(). Trên thực tế, Class<?> thường được sử dụng vì hầu hết các phương pháp trong Class<T> không phụ thuộc vào T.

Ai đó có thể giải thích sự khác biệt giữa ký tự đại diện không ràng buộc và loại thô trong ngôn ngữ của giáo dân.

List<?> khác với List<Object> như thế nào?

+1

Lưu ý rằng cụm từ "loại thô" đề cập đến tham chiếu không tham số cho loại chung, ví dụ: 'Danh sách' so với' Danh sách '. Các khái niệm hơi khác nhau. – Alex

+4

Chỉ cần chỉ ra rằng 'Danh sách ' không phải là một loại thô, loại chung của nó là 'Đối tượng'. Kiểu thô sẽ là 'Danh sách'. – Dmitri

Trả lời

33

Làm thế nào List<?> khác với List<Object>

Sự khác biệt chính là dòng đầu tiên biên dịch nhưng thứ hai không:

List<?> list = new ArrayList<String>(); 
List<Object> list = new ArrayList<String>(); 

Tuy nhiên, bởi vì bạn không biết những gì chung loại List<?> là, bạn không thể sử dụng các phương pháp được tham số hóa của nó:

List<?> list = new ArrayList<String>(); 
list.add("aString"); //does not compile - we don't know it is a List<String> 
list.clear(); //this is fine, does not depend on the generic parameter type 

Đối với sự khác biệt với các loại nguyên liệu (không generics), mã bên dưới biên dịch và chạy tốt:

List list = new ArrayList<String>(); 
list.add("aString"); 
list.add(10); 
+0

đã nhận được nó cho đến nay nhưng làm thế nào loại nguyên liệu là khác nhau cho unbound và tại sao chúng ta cần unboud wildcard? bạn có thể giải thích nó với một số ví dụ hay không. –

+0

@Sandy sự khác biệt chính IMO là việc sử dụng ký tự đại diện không ràng buộc (ví dụ như trong một chữ ký phương pháp) báo hiệu một lời hứa rằng phương pháp được đề cập là nhận thức về generics và sẽ tôn vinh loại chung của đối tượng đó. Với các kiểu thô tất cả các phiên cược đều bị tắt - bạn có thể thêm một số vào danh sách các chuỗi, như minh họa ở đây - và trộn mã chung và thô có thể dẫn đến nguy cơ của ClassCastExceptions. – Alex

+0

@Sandy Tôi minh họa sự khác biệt giữa unbouded (ví dụ thứ 2) và các loại thô (ví dụ 2). Điều gì không rõ ràng về họ? – assylias

4

Làm thế nào List<?> khác với List<Object>?

List<Object> l1 = new ArrayList(); 
    List<?> l2 = new ArrayList(); 
    l1.add("Object"); 
    //l2.add("Object"); incorrect 
    l2.add(null); 

Bạn chỉ có thể thêm null-giá trị cho List<?>

2

Cá nhân, tôi thấy additional link from the Java tutorial on wildcards này hữu ích.

Một trong những khác biệt chính tôi thấy giữa List<?>List là cựu chỉ có thể bao giờ có ích cho việc đọc từ các yếu tố của nó (trừ khi bạn thực sự muốn thêm null), sau này cho phép (đánh dấu) thêm các đối tượng tùy tiện gõ với nó với những tác dụng phụ bất ngờ có thể xảy ra.

0

Danh sách hữu ích trong chữ ký phương thức để gọi các phương thức không bao giờ yêu cầu tham số kiểu, tức là, đọc từ danh sách hoặc xoay vòng, ví dụ.

void someMethod(List<?> list) { 
    list.clear(); // I will never add anything to the list in here 
} 

Bạn sẽ không bao giờ thêm bất cứ điều gì hoặc sửa đổi danh sách liên quan đến việc loại nó giữ như bạn không thể thêm bất cứ điều gì vào danh sách ngoại trừ null trong phương pháp với chữ ký này và do đó bạn sẽ không bao giờ phá vỡ loại an toàn với. Danh sách thô mặt khác, bạn có thể làm bất cứ điều gì, mà như chúng ta đều biết có thể dẫn đến một loại vi phạm an toàn.

void someMethod2(List list) { 
list.add(new WeaselFurBrush()); 
} 
List list1 = new ArrayList<String>(); 
someMethod2(list1);// oops 
Các vấn đề liên quan