2013-08-11 22 views
6

Tôi khá chắc chắn đây là loại an toàn, nhưng chỉ muốn kiểm tra như Eclipse đang yêu cầu tôi đặt một chú thích @SuppressWarnings("unchecked").Loại mã của tôi có an toàn không?

Map<String, IFace> faces; 

public <T extends IFace> T getFace(String key) 
{ 
    return (T) faces.get(key); 
} 
+5

Trả lời câu hỏi của riêng tôi: Không phải vì tôi có thể có hai lớp DIFFERENT 'ClassA' &' ClassB' mà cả hai thực thi 'IFace' trong' khuôn mặt'. Tại thời gian chạy 'T' có thể là' ClassA' hoặc 'ClassB'. – Cheetah

+0

Được gắn dấu sao vì tôi rất quan tâm đến vấn đề tương tự –

+2

Tại sao có các generics ở đây? Nếu bạn chỉ tham chiếu những thứ như 'IFace', thì bạn không cần các generics/casting –

Trả lời

4

Nó không an toàn. Bạn đang upcasting ở đây vì vậy nếu bạn cast vào một lớp học không tương thích có nguồn gốc, bạn sẽ đi qua một lỗi tại một số điểm.

Ví dụ: nếu A_FaceB_Face cả hai đều mở rộng IFace. Bạn có thể tại một số thời điểm được đúc B_Face dưới dạng A_Face không an toàn.

0

Nhìn vào trường hợp cực đoan. Cho phép nói rằng IFace là acutally Object, mã của bạn sau đó trông như thế này:

static Map<String, Object> myMap = new HashMap<>(); 

public static void main(String[] args) throws Exception { 
    myMap.put("ONE", 1); 
    myMap.put("TWO", "TWO"); 
    myMap.put("THREE", new Date()); 

    final Calendar calendar1 = getThing("ONE"); 
    final Calendar calendar2 = getThing("TWO"); 
    final Calendar calendar3 = getThing("THREE"); 
} 

public static <T> T getThing(String key) { 
    return (T) myMap.get(key); 
} 

Vì vậy, bạn đang đặt tại class hơn extends Object vào Map của bạn (vì vậy bất kỳ class).

Tuy nhiên, khi bạn gọi getThing bạn đang thực hiện truyền ngầm đến loại mong muốn của mình. Rõ ràng là tôi cũng có thể gọi số getThing với bất kỳ số class nào và nó sẽ cố gắng truyền đến nó một cách mù quáng.

Trong ví dụ trên, tôi đang đặt một số thứ vào số Map và sau đó cố gắng truy xuất chúng tất cả dưới dạng Calendar s.

0

Một cách cổ điển để xử lý này là với một "container không đồng nhất typesafe":

Map<Class<?>, IFace> faces; 

public <T extends IFace> T getFace(Class<T> key) { 
    return t.cast(faces.get(key)); 
} 

Bạn sử dụng lớp của giao diện như một chìa khóa, chứ không phải là một chuỗi, và sau đó bạn có thể sử dụng các lớp đều đạt như một chìa khóa để đúc một cách an toàn giá trị trả lại cho đúng loại.