2016-01-30 16 views
5
List<? extends String> list = new Arraylist<String>(); 
list.add("foo"); 

Đoạn mã đã cho tôi lỗi thời gian biên dịch.không hiểu vì sao tôi không thể thêm chuỗi trong danh sách. nhưng mã có nghĩa là chúng ta có thể thêm đối tượng lớp String và đối tượng lớp dẫn xuất của nó trong danh sách tôi vẫn nhận được lỗi tại saoLỗi thời gian biên dịch khi sử dụng ký tự đại diện trong Danh sách

+1

Nó không thực sự có ý nghĩa, vì 'Chuỗi' là một ** ** cuối cùng lớp! Không có lớp nào có thể mở rộng 'Chuỗi'. Vì vậy, điều duy nhất bạn nên làm là xác định nó là 'Danh sách '. – bobbel

+0

nhưng làm thế nào nó lấy tham chiếu của ArrayList có String là đối tượng của nó? –

+0

Vì 'Danh sách ' thỏa mãn 'Danh sách '. Sự khác biệt là * Chuỗi là một String * nhưng * Chuỗi có thể không phải là một? đó là một String *. – Linus

Trả lời

2

List<?> chỉ nên được sử dụng khi bạn không quan tâm đến kiểu dữ liệu của các mục và quan tâm đến các hoạt động như nhận được kích thước của danh sách, vv

Ví dụ,

public int getSize(List<?> itemList) { 
    return itemList.size(); 
} 

Nó là nhiều hơn một danh sách Read Only.

Bạn nên sử dụng phần sau nếu bạn định tạo danh sách mới gồm String mục.

List<String> list = new Arraylist<>(); 
list.add("foo"); 

Ngoài ra, bạn có thể sử dụng này:

List<Object> list = new Arraylist<>(); 
list.add("foo"); 
1

này sẽ làm việc:

List<? super String> list = new ArrayList<String>(); 
list.add("foo"); 

Sau đó trình biên dịch của bạn sẽ bây giờ, mà người gọi là phải vượt qua một danh sách các đối tượng là String hoặc loại siêu.

Khi bạn nói <? extends String> nghĩa là nó có thể thuộc bất kỳ loại nào mở rộng String. Điều đó có nghĩa là ai đó có thể vượt qua List và nó sẽ chấp nhận nó.

Look cũng ở đây: Difference for <? super/extends String> in method and variable declaration

1

Về cơ bản List<? extends String> là một danh sách có kiểu không rõ, tất cả những gì được biết đến là loại hình này kéo dài chuỗi. Nó không quan trọng là biến chứa một thể hiện của List<String>.

Bây giờ String là cuối cùng, vì vậy không có lớp con ... vì vậy hãy cân nhắc:

List<? extends A> list = new ArrayList<A>(); 

nơi A là một số lớp với một lớp con B. Khi được sử dụng, một biến loại List<? extends A> có thể là một phiên bản của List<B>. Chúng tôi không thể thêm A vào nó vì có khả năng là A không phải là B.

Nhưng bạn biết điều đó sẽ đúng? Vâng, trình biên dịch không, cũng không dự đoán các kết nối logic giữa loại không xác định và những gì bạn đã khởi tạo, bởi vì nói chung bạn có thể thay đổi biến đó khi chạy.

Một ví dụ tương tự tồn tại trong hướng dẫn một cách lạc quan tên More Fun with Wildcards, nơi một phương pháp chấp nhận (Set<T>, T) và một cuộc gọi bất hợp pháp được sử dụng preposed (Set<?>, String) dù biến Set<?> chứa một thể hiện của Set<String>. Vấn đề là như nhau ở đây, mặc dù bổ sung extends.

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