Tôi dường như có một sự hiểu lầm về sự khác biệt giữa <Foo>và <? extends Foo>. Theo hiểu biết của tôi, nếu chúng ta có
ArrayList<Foo> foos = new ArrayList<>();
Điều này chỉ ra rằng các đối tượng kiểu Foocó thể được thêm vào danh sách mảng này. Vì các lớp con Foocũng thuộc loại Foo, chúng cũng có thể được thêm vào mà không có lỗi, như được minh họa bởi
ArrayList<Foo> foos = new ArrayList<>();
foos.add(new Foo());
foos.add(new Bar());
nơi Bar extends Foo.
Bây giờ, nói rằng tôi đã định nghĩa fooslà
ArrayList<? extends Foo> foos = new ArrayList<>();
Sự hiểu biết hiện tại của tôi là điều này thể hiện some unknown type that extends Foo. Tôi hiểu điều này có nghĩa là bất kỳ đối tượng nào là một lớp con Foocó thể được thêm vào danh sách này; có nghĩa là không có sự khác biệt giữa ArrayList<Foo>và ArrayList<? extends Foo>.
Để kiểm tra điều này, tôi đã thử viết đoạn mã sau
ArrayList<? extends Foo> subFoos = new ArrayList<>();
subFoos.add(new Foo());
subFoos.add(new Bar());
nhưng đã được nhắc với lỗi biên dịch sau
no suitable method found for add(Foo)
method java.util.Collection.add(capture#1 of ? extends Foo) is not applicable
(argument mismatch; Foo cannot be converted to capture#1 of ? extends Foo)
no suitable method found for add(Bar)
method java.util.Collection.add(capture#2 of ? extends Bar) is not applicable
(argument mismatch; Bar cannot be converted to capture#2 of ? extends Bar)
Dựa trên sự hiểu biết hiện tại của tôi, tôi có thể thấy lý do tại sao tôi không thể thêm Foomột danh sách vào <? extends Foo>, bởi vì nó không phải là một lớp con của chính nó; nhưng tôi tò mò về lý do tại sao tôi không thể thêm một Bardanh sách.
Đâu là lỗ hổng trong sự hiểu biết của tôi?
<? extends Foo>là một lớp học cụ thể và chưa biết kéo dài Foo. Một hoạt động với lớp này chỉ hợp pháp nếu nó là hợp pháp cho bất kỳ lớp con nàoFoo .