Tôi bắt gặp một cái gì đó rất cơ bản nhưng cực kỳ hoang mang ngày nay. Tôi cần chuyển đổi một danh sách thành một mảng. Danh sách chứa String
trường hợp. Ví dụ hoàn hảo về việc sử dụng List.toArray(T[])
, vì tôi muốn một phiên bản String[]
. Nó sẽ không hoạt động, tuy nhiên, mà không rõ ràng đúc kết quả đến String[]
.Hành vi generics Odd của List.toArray (T [])
Như một kịch bản thử nghiệm, tôi đã sử dụng đoạn mã sau:
import java.util.Arrays;
import java.util.List;
public class MainClass {
public static void main(String args[]) {
List l = Arrays.asList("a", "b", "c");
String stuff[] = l.toArray(new String[0]);
System.err.println(Arrays.asList(stuff));
}
}
mà không biên dịch. Đó là gần một bản sao chính xác của ví dụ trong javadoc, nhưng trình biên dịch cho biết như sau:
MainClass.java:7: incompatible types
found : java.lang.Object[]
required: java.lang.String[]
String stuff[] = l.toArray(new String[0]);
^
Nếu tôi thêm một dàn diễn viên để String[]
nó sẽ biên dịch và chạy một cách hoàn hảo. Nhưng đó không phải là những gì tôi mong đợi khi tôi nhìn vào chữ ký của phương pháp toArray:
<T> T[] toArray(T[] a)
Điều này nói với tôi rằng tôi không nên bỏ. Chuyện gì vậy?
Edit:
Tò mò, nếu tôi thay đổi việc kê khai danh sách công việc:
List<?> l = Arrays.asList("a", "b", "c");
nó cũng làm việc. Hoặc List<Object>
. Vì vậy, nó không phải là một List<String>
như đã được đề xuất. Tôi bắt đầu nghĩ rằng việc sử dụng kiểu thô List
cũng thay đổi cách các phương thức chung trong lớp đó hoạt động.
Chỉnh sửa thứ hai:
Tôi nghĩ mình đã hiểu ngay bây giờ. Những gì Tom Hawtin đã viết trong một bình luận dưới đây có vẻ là giải thích tốt nhất. Nếu bạn sử dụng một kiểu generic theo cách thô, tất cả các thông tin generics từ cá thể đó sẽ bị xóa bởi trình biên dịch.
Điều này có ý nghĩa đối với tôi một cách hợp lý, nhưng không phải về mặt kỹ thuật. Nó không nhìn vào tôi rằng phương thức toArray quan tâm đến những gì E bị ràng buộc (tức là, lớp phần tử của danh sách). – waxwing
chữ ký của toArray là "công khai T [] toArray (T [] a)", T là loại thành phần của mảng được truyền trong –
dfa
Tôi cũng không thể hiểu nó, tệ hơn là nó cũng hoạt động bằng cách sử dụng Danh sách