2013-08-22 40 views
13

Sự khác nhau giữa <? extends Object><E extends Object> là gì? Khi nào người ta nên sử dụng cái kia?Sự khác nhau giữa <? mở rộng Object> và <E mở rộng Object>?

+7

Bạn có thể sử dụng lại 'E'. –

+0

Chúng loại trừ lẫn nhau. – SLaks

+0

IMO Tôi sẽ sử dụng ' 'trong' static' các phương thức tiện ích để xử lý các phần tử của một tập hợp (set, list, map, etc) và không có gì nữa, và tôi sẽ sử dụng '' cho định nghĩa lớp/giao diện trong trường hợp tôi muốn các trường (trường kiểu E hoặc tập hợp chứa các phần tử thuộc loại E). –

Trả lời

4

<? extends Object> là một bị chặn wildcard (một người vô danh mà kéo dài Object, trong khi <E extends Object> là loại giáp (E đòi hỏi một loại tham số mà kéo dài Object).

khác biệt tinh tế Hầu hết giáp ký tự đại diện từ phía trên tham số bị ràng buộc:

  • Không thể sử dụng ký tự đại diện bị ràng buộc khi tạo tham số Kiểu chung s được cho phép.

  • Không thể sử dụng ký tự đại diện bị ràng buộc trong Collection s nơi yêu cầu thêm các mục trong bộ sưu tập vì nó là loại không xác định và bộ sưu tập không biết loại nào đang nhận. .

  • Ký tự đại diện bị ràng buộc không thể bị ràng buộc với nhiều loại chung chung (giới hạn).

Tôi hy vọng điều này sẽ hữu ích.

+0

cả hai ' 'và' 'được giới hạn, chúng có giới hạn trên' Object' – Katona

+0

Đúng, tôi đã chỉnh sửa để tạo sự khác biệt giữa 2 ... –

+0

Thực tế sử dụng ký tự đại diện trong Bộ sưu tập nơi cần thêm mục có thể được thực hiện nếu ký tự đại diện là loại

3

Sử dụng E nếu bạn cần tham khảo loại sau này. Sử dụng ? nếu bạn không bao giờ phải tham khảo lại loại.

-1

<E> khai báo đối số loại.
Bạn chỉ có thể sử dụng nó khi tạo loại hoặc phương pháp chung.

<? ...> là ký tự đại diện giá trị đối số loại.
Bạn chỉ có thể sử dụng nó khi tạo loại chung đóng.

0

Trong mã chung, dấu hỏi (?), Được gọi là ký tự đại diện, đại diện cho một loại không xác định. Ký tự đại diện có thể được sử dụng trong nhiều tình huống khác nhau: dưới dạng kiểu tham số, trường hoặc biến cục bộ; đôi khi là một kiểu trả về (mặc dù nó là thực hành lập trình tốt hơn để cụ thể hơn). Ký tự đại diện không bao giờ được sử dụng như một đối số kiểu cho một lời gọi phương thức chung, một cá thể lớp chung tạo hoặc một siêu kiểu. Để biết thêm thông kiểm tra this

15

Dưới đây là một số khác biệt mà ngay lập tức nói đến cái tâm của tôi:

  • Loại giới hạn thông số có thể chỉ định nhiều giới hạn - T extends A & B, nhưng với ký tự đại diện, bạn không thể chỉ định nhiều giới hạn - ? extends A & B không hợp lệ.

  • Bạn có thể có giới hạn dưới với ký tự đại diện - ? super A hợp lệ nhưng không hợp lệ với thông số loại - T super A không hợp lệ.

  • Bạn không thể sử dụng giới hạn ký tự đại diện khi tạo loại chung. Bạn phải sử dụng giới hạn tham số kiểu.

  • Bên trong một phương thức, nếu bạn muốn một số mối quan hệ giữa các tham số kiểu của các đối số được truyền, thì bạn phải sử dụng các tham số kiểu tham số. Ví dụ: bạn muốn chuyển hai loại tham số có cùng tham số kiểu. Bạn không thể làm điều này với giới hạn ký tự đại diện. Vì vậy, khai báo phương thức sau sẽ lấy hai danh sách cùng một tham số kiểu, mở rộng Number.

    public <T extends Number> void merge(List<T> list1, List<T> list2) { 
    } 
    

Để kết thúc với, tôi sẽ thêm một số điểm từ Java hiệu quả - Mục 28: Sử dụng ký tự đại diện giáp để tăng tính linh hoạt API:

Đối với sự linh hoạt tối đa, sử dụng các loại ký tự đại diện về các thông số đầu vào đại diện cho nhà sản xuất hoặc người tiêu dùng. Nếu tham số đầu vào vừa là nhà sản xuất vừa là người tiêu dùng, thì các loại ký tự đại diện sẽ không làm bạn tốt: bạn cần khớp chính xác, đó là những gì bạn nhận được mà không có bất kỳ ký tự đại diện nào.

Không sử dụng các loại ký tự đại diện làm loại trả lại. Thay vì cung cấp sự linh hoạt bổ sung cho người dùng của bạn, nó sẽ buộc họ sử dụng các loại ký tự đại diện trong mã máy khách. Được sử dụng đúng cách, các loại ký tự đại diện gần như vô hình đối với người dùng của một lớp. Chúng gây ra các phương thức chấp nhận các tham số mà chúng nên chấp nhận và từ chối các tham số mà chúng nên từ chối. Nếu người dùng của một lớp phải suy nghĩ về các loại ký tự đại diện, có thể có sự cố với API của lớp học.


Tài liệu tham khảo:

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