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 Foo
có thể được thêm vào danh sách mảng này. Vì các lớp con Foo
cũ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 foos
là
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 Foo
có 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 Foo
mộ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 Bar
danh 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
.