关于java中的通用转换

Wei*_*Lin 1 java generics types casting

在Java中,每个人都知道Integer不能转换为String,这在编译时是一个错误.

现在对于这个通用案例,

        public <T> T cast(Object o) {
            return (T) Integer.class.cast(o);//cast Integer to T
        }

        void method1() {
            String q = cast("q"); //T is String
        }
Run Code Online (Sandbox Code Playgroud)

我只是不明白为什么在这种情况下java不能在编译时警告你Integer被强制转换为String.为什么?在我的知识中,类型擦除是在编译后发生的.

编辑:我只是认为编译器有类型推断知道T是String,因此无法转换为Integer.但显然它不是.

Sot*_*lis 5

有了这个

public <T> T cast(Object o) {
     return (T) Integer.class.cast(o);//cast Integer to T
}
Run Code Online (Sandbox Code Playgroud)

你声明一个T无界的类型变量,即.它可以是任何引用类型.因此cast,Integer可能会工作,也可能不会.

所有编译器都能做的就是警告你

类型安全:未选中从Integer到T的强制转换

相反,如果你给了类型变量的边界,那就像

public <T extends CharSequence> T cast(Object o) {
    return (T) Integer.class.cast(o); // Cannot cast from Integer to T
}
Run Code Online (Sandbox Code Playgroud)

那么你会很得到一个编译错误,因为CharSequenceInteger没有在同一个继承层次,因此不兼容.

在这种特定情况下,即使没有强制转换,您也会收到编译错误T.这是因为

AnyTypeName.class 
Run Code Online (Sandbox Code Playgroud)

始终返回a Class<ThatTypeName>Class#cast使用泛型类型.在这种情况下,它将返回一个Integer并且Integer不可转换为T.