2010-11-19 46 views
5

Tôi mong đợi mã này sẽ ném một ClassCastException:Tại sao diễn viên chung này không thành công?

public class Generics { 
    public static void main(String[] args) { 
     method(Integer.class); 
    } 

    public static <T> T method(Class<T> t) { 
     return (T) new String(); 
    } 
} 

Nhưng nó không. Đúc String để T không thất bại, cho đến khi tôi sử dụng đối tượng quay trở lại bằng cách nào đó, như:

public class Generics { 
    public static void main(String[] args) { 
     method(Integer.class).intValue(); 
    } 

    public static <T> T method(Class<T> t) { 
     return (T) new String(); 
    } 
} 

Bối cảnh: Tôi tạo ra một lớp trong đó sử dụng JAXB để unmarshal một tập tin XML. Có vẻ như sau:

public static <T> T unmarshal(File file, Class<? extends T> clazz) 

Tùy thuộc vào liệu phần tử gốc có phải là loại ẩn danh hay không, hoặc T hoặc JAXBElement đang được trả lại. JAXBElement tất nhiên, không thể được đúc vào T. Trong bài kiểm tra đơn vị của tôi, nơi tôi chỉ được gọi là unmarshal() mà không làm điều gì đó với kết quả, mọi thứ đều hoạt động tốt. Trong Mã, nó không thành công.

Tại sao nó không trực tiếp thất bại? Đây có phải là một lỗi? Nếu không, tôi muốn hiểu tại sao.

+1

Vâng, nó * có * tạo ra cảnh báo. – Jeremy

Trả lời

4

Bạn không chỉ định rõ ràng, vì vậy T là đối tượng.

Vì vậy, nhìn lên nhìn như thế này

public class Generics { 

    public static void main(String[] args) { 
     Generics.method(Integer.class).intValue(); 
    } 

    public static Object method(Class<Object> t) { 
     return (Object) new String(); 
    } 
} 

Nếu bạn chỉ định tham số chung:

public class Generics { 

    public static void main(String[] args) { 
     Generics.<Integer>method(Integer.class).intValue(); 
    } 

    public static <T> T method(Class<T> t) { 
     return (T) new String(); 
    } 
} 

Bạn sẽ nhận được ngoại lệ đó.

4

Nếu T không được chỉ định rõ ràng, loại xóa sẽ xử lý nó là Object. Vì vậy, đối tượng String của bạn có thể được đúc ...

1

Tôi nghĩ rằng bạn có thể làm cho định nghĩa phương pháp mạnh hơn như thế này:

public static <T extends Number> T method(Class<T> t) { 
    return //// some code. 
} 

Phù trường hợp này trở new String() chỉ là không thể được biên dịch.

nhưng dòng trả về số nguyên mới (123); được biên dịch, hoạt động và không yêu cầu truyền.

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