Tôi đang đọc về các phương thức chung từ OracleDocGenericMethod . Tôi khá bối rối về sự so sánh khi nó cho biết khi nào sử dụng wild-card và khi nào sử dụng các phương pháp chung. Trích dẫn từ tài liệu.
interface Collection<E> { public boolean containsAll(Collection<?> c); public boolean addAll(Collection<? extends E> c); }
Chúng tôi có thể đã sử dụng các phương pháp chung ở đây để thay thế:
interface Collection<E> { public <T> boolean containsAll(Collection<T> c); public <T extends E> boolean addAll(Collection<T> c); // Hey, type variables can have bounds too! }
[…] Điều này cho chúng ta biết rằng đối số kiểu đang được sử dụng cho tính đa hình; tác dụng duy nhất của nó là cho phép nhiều kiểu đối số thực tế được sử dụng tại các vị trí gọi khác nhau. Nếu đúng như vậy, người ta nên sử dụng các ký tự đại diện. Các ký tự đại diện được thiết kế để hỗ trợ nhập phụ linh hoạt, đó là những gì chúng tôi đang cố gắng thể hiện ở đây.
Chúng tôi không nghĩ rằng thẻ hoang dã như (Collection<? extends E> c);
cũng đang hỗ trợ loại đa hình? Sau đó, tại sao việc sử dụng phương pháp chung được coi là không tốt trong điều này?
Tiếp tục phía trước, nó nói,
Các phương thức chung cho phép các tham số kiểu được sử dụng để thể hiện sự phụ thuộc giữa các kiểu của một hoặc nhiều đối số đối với một phương thức và / hoặc kiểu trả về của nó. Nếu không có sự phụ thuộc như vậy, không nên sử dụng phương pháp chung.
Điều đó có nghĩa là gì?
Họ đã trình bày ví dụ
class Collections { public static <T> void copy(List<T> dest, List<? extends T> src) { ... }
[…]
Chúng tôi có thể viết chữ ký cho phương pháp này theo cách khác, mà không cần sử dụng ký tự đại diện:
class Collections { public static <T, S extends T> void copy(List<T> dest, List<S> src) { ... }
Tài liệu không khuyến khích khai báo thứ hai và khuyến khích sử dụng cú pháp đầu tiên? Sự khác biệt giữa khai báo thứ nhất và thứ hai là gì? Cả hai dường như đang làm cùng một điều?
Ai đó có thể đặt ánh sáng cho khu vực này.
?
. Bạn có thể viết lại nó thành `public static <T1 expand Number, T2 expand Number> void copy (List <T1> dest, List <T2> src) và trong trường hợp này, nó trở nên rõ ràng những gì đang xảy ra.