2010-11-12 45 views
16

Trong Java khi truyền từ một đối tượng sang các loại khác, tại sao dòng thứ hai lại đưa ra cảnh báo liên quan đến phép đúc, nhưng đầu tiên không xuất hiện?Java: Đúc đối tượng vào kiểu chung

void a(Object o) { 
    Integer i = (Integer) o; 
    List<Integer> list = (List<Integer>) o; 
} 

/*Type safety: Unchecked cast from Object to List<Integer>*/ 
+0

Dòng thứ hai tạo ra cảnh báo vì chỉ có Generics tạo ra cảnh báo như vậy. Việc đầu tiên không chứa chung chung, do đó không có cảnh báo. –

Trả lời

24

Đó là vì đối tượng sẽ không thực sự được kiểm tra là một List<Integer> tại thời gian thực hiện do loại chô bôi. Nó sẽ thực sự chỉ được đúc nó đến List. Ví dụ:

List<String> strings = new ArrayList<String>(); 
strings.add("x"); 
Object o = strings; 

// Warning, but will succeeed at execution time 
List<Integer> integers = (List<Integer>) o; 
Integer i = integers.get(0); // Bang! 

Xem Angelika Langer's Java Generics FAQ để biết thêm thông tin, đặc biệt là type erasure section.

5

Câu trả lời của Jon là câu trả lời đúng, nhưng đôi khi bạn không thể tránh được cảnh báo đó (như khi bạn đang làm việc với API cũ). Trong những trường hợp, bạn có thể ngăn chặn các cảnh báo như vậy:

@SuppressWarnings("unchecked") 
List<Integer> list = (List<Integer>) someApiThatReturnsNonGenericList(); 
6

Để làm rõ, hãy để tôi hơi viết lại ví dụ ...

Tôi xin nói, các chênh lệch cruxial giữa:

void a(Object o) { 
    Integer i = (Integer) o; 
    ... 
} 

void a(Object o) { 
    List<Integer> list = (List<Integer>) o; 
    ... 
} 

là, cho rằng có lỗi loại, lần truyền đầu tiên sẽ luôn là ngay lập tức ném một RuntimeException (cụ thể là một ClassCastException) khi được thực thi.

Trong khi thứ hai sức mạnh không - miễn là các tham số đầu vào o là bất kỳ loại List<?>, thực hiện sẽ chỉ cần tiến hành, mặc dù của một dàn diễn viên không chính xác.

Cho dù mã sẽ ở đâu đó sau ném ngoại lệ hay không, tùy thuộc vào những gì bạn làm với danh sách.

Nhưng không quan tâm, ngoại lệ có thể không được ném tại dòng nơi dàn diễn viên được thực hiện, nhưng ở một nơi khác (có thể là một lỗi khó khăn để theo dõi) hoặc hoàn toàn không.

Đó là những gì tôi hiểu, là lý do mà các nhà thiết kế trình biên dịch coi là một cảnh báo chỉ thích hợp trong trường hợp thứ hai.

+1

Giải thích tuyệt vời. – Trilarion

+0

Đầu tiên * sẽ không * luôn ném CastClassException. Đối tượng đến có thể rất tốt là một 'Integer'. Dòng đầu tiên MIGHT ném một ngoại lệ, giống như thứ hai có thể nếu 'o' không phải là một' Danh sách'. –

+0

@Hot Licks: vâng, đó là lý do tại sao tôi đã viết "cho rằng có một loại lỗi" ở trên - tôi thậm chí đặt in đậm;) – Rop

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