2009-08-05 34 views
8

Nếu bạn có một phương pháp với chữ ký:Java lớp generized tham khảo

Class<? extends List<String>> getObjectType() 
{ 
     return ?????; 
} 

Làm thế nào để bạn quay lại một phiên bản generic thích hợp của lớp Danh sách?

return List.class; //errors 
return List<String>.class; //errors 
return List.class<String>; //errors 

cú pháp thích hợp để xử lý việc này là gì?

Trả lời

9

Bạn cần truyền rõ ràng loại trả về. Công trình này:

return (Class<? extends List<String>>) List.class; 

Có vẻ như không đúng. Đây chỉ là một trong nhiều lý do hệ thống Generics của Java là một mớ hỗn độn.

+0

Thú vị, làm đề xuất của bạn được tôi gần như nhật thực ngừng phàn nàn. nhưng khi tôi biên dịch lớp với trình biên dịch java, tôi nhận được "các loại không thể tìm thấy được: java.lang.Class được yêu cầu: java.lang.Class > " –

+0

Rất tiếc, nó hoạt động cho tôi trong nhật thực, nhưng không phải khi được biên dịch trên dòng lệnh. Tôi chưa bao giờ thấy điều đó trước đây. –

+0

Với tùy chọn -nowarn nó hoạt động cho trường hợp trả về someList.getClass(), nhưng tôi vẫn nhận được cùng một lỗi mà bạn đang thấy khi thử nó với List.class. –

2

Bạn phải trả lại lớp của thứ gì đó mở rộng List<String>. ArrayList<String> là một ví dụ. Bạn có thể thử:

ArrayList<String> myList = new ArrayList<String>(); 
... 
return (Class<? extends List<String>>)myList.getClass(); 
+1

Dàn diễn viên rõ ràng là cần thiết. Phương thức getClass chung trả về kiểu Class . –

+0

@John: Cảm ơn bạn đã chỉ ra điều đó. Tôi đã kiểm tra, và đó thực sự là trường hợp. Tôi đã cập nhật ví dụ của mình để bao gồm dàn diễn viên. –

5

Từ sách "Java hiệu dụng" (Ấn bản thứ hai, trang 137): "Không sử dụng các loại ký tự đại diện làm loại trả lại. sử dụng các loại ký tự đại diện trong mã khách hàng của họ. "

Điều đó nói rằng, để cast, trước tiên bạn phải tạo một biến tạm thời:

@SuppressWarnings("unchecked") 
Class<? extends List<String>> result = ....; 
return result; 

này hoạt động bởi vì bạn có thể có nhiều chú thích trên các bài tập. Nó không hoạt động trên return. Bạn cũng có thể thêm nó vào phương thức nhưng điều đó cũng sẽ ẩn các vấn đề khác.

+1

Đối với tôi nó không chỉ cảnh báo, nó thực sự tạo ra một lỗi biên dịch cho đến khi tôi thêm vào dàn diễn viên. –

+0

Đúng. "Danh sách" và "Danh sách <...>" là các loại hoàn toàn khác nhau (giống như Chuỗi và Số nguyên), vì vậy bạn cần có dàn diễn viên. Nhưng các diễn viên sẽ gây ra một cảnh báo và bạn cần phải ngăn chặn điều đó. –

0

Danh sách.class và Danh sách < Chuỗi > .class - trong tất cả trường hợp này bạn cần truyền. Thực sự bạn cần một loại, có Danh sách < Chuỗi > lúc chạy, somethig như thế này:

interface StringList extends List<String> {}; 

public Class<? extends List<String>> getObjectType() { 
    return StringList.class; 
} 
Các vấn đề liên quan