Ngược lại với .NET Generics Java được triển khai bằng kỹ thuật được gọi là "loại tẩy xoá".
Điều này có nghĩa là trình biên dịch sẽ sử dụng thông tin loại khi tạo tệp lớp, nhưng không chuyển thông tin này sang mã byte. Nếu bạn xem các lớp được biên dịch bằng javap hoặc các công cụ tương tự, bạn sẽ thấy rằng List<String>
là một đơn giản List
(trong số Object
) trong tệp lớp, giống như trong mã Java-5 trước.
Mã truy cập danh sách chung sẽ được "viết lại" bởi trình biên dịch để bao gồm các phôi bạn sẽ phải tự viết trong các phiên bản trước đó. Trên thực tế hai đoạn mã sau đây là giống hệt nhau từ góc độ mã byte khi trình biên dịch được thực hiện với họ:
Java 5:
List<String> stringList = new ArrayList<String>();
stringList.add("Hello World");
String hw = stringList.get(0);
Java 1.4 và trước:
List stringList = new ArrayList();
stringList.add("Hello World");
String hw = (String)stringList.get(0);
Khi đọc các giá trị từ một lớp chung trong Java 5 cần thiết cho tham số kiểu khai báo được chèn tự động. Khi chèn, trình biên dịch sẽ kiểm tra giá trị bạn cố gắng đặt vào và hủy bỏ với một lỗi nếu nó không phải là một String.
Toàn bộ điều đã được thực hiện để giữ cho các thư viện cũ và mã tổng hợp mới có khả năng tương tác mà không cần phải biên dịch lại các thư viện hiện có. Đây là một lợi thế lớn so với cách thức .NET, nơi các lớp chung và các lớp không chung chung sống song song nhưng không thể trao đổi một cách tự do.
Cả hai cách tiếp cận đều có ưu và nhược điểm của chúng, nhưng đó là cách nó có trong Java.
Để quay lại câu hỏi ban đầu: Bạn sẽ không thể nhận được thông tin loại lúc chạy, bởi vì nó đơn giản không còn ở đó nữa, khi trình biên dịch đã thực hiện công việc của mình. Điều này là chắc chắn hạn chế trong một số cách và có một số cách cranky xung quanh nó mà thường được dựa trên lưu trữ một trường hợp ở đâu đó, nhưng đây không phải là một tính năng tiêu chuẩn.
Nguồn
2009-06-16 21:44:29
Mong muốn thực hiện điều này hầu như được bảo đảm là một lựa chọn thiết kế xấu. Rất có thể là câu lệnh if đòi hỏi kiến thức về từng loại "" để được triển khai, vì vậy bạn có lẽ nên có tất cả các lớp đó có cùng kiểu gốc, và "làm điều này" phải là một phương thức ảo. Nó có thể liên quan đến các lớp học gói, nhưng tổng thể thiết kế của bạn sẽ cải thiện nếu bạn đi xuống con đường này. –
Các khả năng trong các câu lệnh if là các trường hợp cạnh trong số tất cả các loại cuộc gọi có thể yêu cầu hoàn toàn việc triển khai riêng biệt hoàn toàn. Tôi đồng ý với những gì bạn đang nói ở đây, nhưng ứng dụng cụ thể là một tảng đá và một nơi khó khăn. –
Sự cần thiết để có được các lớp cho một param loại chung chung không phải luôn luôn là một quyết định thiết kế xấu. Một yêu cầu hợp pháp (của tôi! :) có thể là một cuộc gọi phương thức yêu cầu tham số Class <>. – dahvyd