2010-06-07 23 views
19

Có rất nhiều câu hỏi về stackoverflow từ những người đã cố gắng để tạo ra một loạt các Generics như vậy:Tại sao Java không cho phép tạo mảng chung?

ArrayList<Foo>[] poo = new ArrayList<Foo>[5]; 

Và câu trả lời dĩ nhiên là các đặc điểm kỹ thuật Java không cho phép bạn khai báo một mảng của generics.

Tuy nhiên, câu hỏi của tôi là lý do tại sao? Lý do kỹ thuật cơ bản hạn chế này trong ngôn ngữ java hoặc java vm là gì? Đó là một sự tò mò về kỹ thuật mà tôi luôn tự hỏi.

Trả lời

13

Mảng được hợp nhất - chúng giữ lại thông tin loại khi chạy.

Generics là một cấu trúc biên dịch - thông tin kiểu bị mất khi chạy. Đây là một quyết định có chủ ý để cho phép tương thích ngược với Java bytecode tiền chất. Hậu quả là bạn không thể tạo một mảng kiểu generic, bởi vì vào thời điểm VM muốn tạo mảng, nó sẽ không biết loại nào sẽ sử dụng.

5
+0

Java hiệu quả thực sự là một cuốn sách tuyệt vời. Tôi đã thấy nhiều câu hỏi tôi nhận được trong các cuộc phỏng vấn trên cuốn sách này. – zihaoyu

3

Dưới đây là một bài viết trên blog cũ tôi đã viết mà tôi giải thích vấn đề: Java generics quirks

Xem How do I generically create objects and arrays? từ Java Generics FAQ Angelika Langer cho một workaround (bạn có thể làm điều đó bằng phản ánh). Câu hỏi thường gặp đó chứa tất cả mọi thứ bạn muốn biết về Generics Java.

+0

Trang blog được lưu trữ bởi chủ nhân cũ của tôi và không còn tồn tại nữa. – Jesper

0

Bạn đang buộc phải sử dụng

ArrayList<Foo>[] poo = new ArrayList[5]; 

mà sẽ cung cấp cho bạn một cảnh báo không được kiểm soát. Lý do là có một vấn đề an toàn kiểu tiềm năng với generics và hành vi kiểm tra kiểu runtime của các mảng Java, và chúng muốn đảm bảo rằng bạn nhận thức được điều này khi bạn lập trình. Khi bạn viết new ArrayList[...], bạn đang tạo một cái gì đó sẽ kiểm tra, tại thời gian chạy, tất cả mọi thứ được đưa vào nó để đảm bảo rằng nó là một ví dụ của ArrayList. Theo kế hoạch này, khi bạn làm new ArrayList<Foo>[...], sau đó bạn mong đợi để tạo ra một cái gì đó kiểm tra tại thời gian chạy tất cả mọi thứ được đưa vào nó để đảm bảo nó là một ví dụ của ArrayList<Foo>. Nhưng điều này là không thể làm trong thời gian chạy, bởi vì không có thông tin generics trong thời gian chạy.

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