Tại sao java generic không thể ở trong mảng?


10

Tại sao khi tôi cố gắng tạo một mảng ArrayLists: ArrayList<Integer>[] arr=new ArrayList<Integer>[40];có lỗi và java không cho phép điều này?

Có một lý do liên quan đến việc java thực hiện các khái quát, khái quát trong bất kỳ ngôn ngữ nào, hoặc một cái gì đó tùy ý?


Câu trả lời:


20

Đây là một trong những lỗ hổng lớn trong các tổng quát của Java, các mảng là covariant , có nghĩa là một mảng kiểu Foo[]là một lớp con của Object[]ParentOfFoo[]. Tương phản điều này List<Foo>mà không có hành vi này.

Điều này rất quan trọng khi Java không có khái quát (cho đến Java 5) bởi vì nếu không, một cái gì đó giống như một hàm sắp xếp chung là không thể.

Tuy nhiên, vấn đề phức tạp này là các mảng muốn biết loại nào trong thời gian chạy . Tuy nhiên, thuốc generic trong Java dựa trên kiểu xóa. Hai điều này hoàn toàn không phù hợp và đó là vấn đề chúng ta gặp phải.

Vì vậy, dài và ngắn của nó là, trong Java 1, các mảng covariant đã lấp đầy một phần lỗ hổng mà thiếu tính tổng quát tạo ra. Tuy nhiên, khi họ cố gắng lấp đầy lỗ hổng này, khả năng tương thích ngược có nghĩa là các mảng khá khó thực hiện.

Trên thực tế, anh chàng thực sự đã tạo ra khuôn khổ cho thuốc generic, Martin Oderky, đã nói về điều này ở đây trong một cuộc phỏng vấn về lý do tại sao anh ta tạo ra Scala. (Khá hấp dẫn nếu bạn quan tâm đến lịch sử của Scala)


3

Có một lý do liên quan đến việc java thực hiện các khái quát, khái quát trong bất kỳ ngôn ngữ nào, hoặc một cái gì đó tùy ý?

Thật ra, nó hơi độc đoán.

Vấn đề là nó cho phép một lỗ hổng trong hệ thống loại, vì ArrayList<T>[]có thể được truyền tới Object[]và sau đó bạn có thể đặt một ArrayList<U>mảng trong đó U != T.

Các nhà thiết kế Java đã quyết định chặn lỗ hổng này một cách háo hức nhất có thể, bằng cách không cho phép new ArrayList<T>[N]chút nào.

Tuy nhiên, nó cũng có thể đã được cắm bằng cách không cho phép chiếu lên các mảng tổng quát (không có cảnh báo "không được kiểm soát").


Câu trả lời này được đánh giá thấp. Rất đơn giản và không sử dụng biệt ngữ về các thuật ngữ mơ hồ. Cảm ơn rất nhiều.
Tung Nguyễn

Bạn có thể muốn giải thích lý do tại sao điều này khác với trường hợp bạn đặt Integermột Object[]thứ thực sự làString[]
Caleth

-3

bởi vì mảng là covariant mà mọi kiểu là một lớp con của đối tượng nên điều này gây ra lỗi trong thời gian chạy do ngoại lệ truyền. trong khi cái chung là bất biến nên khi nó xây dựng trên kiểu đảm bảo hoặc loại an toàn vì vậy nếu kiểu không giống như nó tạo ra kiểu thì nó sẽ báo lỗi trình biên dịch.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.