Java泛型中没有抛出ClassCastException

Java泛型中没有抛出ClassCastException,java,generics,classcastexception,Java,Generics,Classcastexception,下面是我编写的第一个Java泛型: public class MyClass { public static <T> T castToAnotherType(Object param) { T ret = null; try { ret = (T) param; } catch (ClassCastException e) { System.out.print("Exceptio

下面是我编写的第一个Java泛型:

public class MyClass {

    public static <T> T castToAnotherType(Object param) {
        T ret = null;
        try {
            ret = (T) param;
        } catch (ClassCastException e) {
            System.out.print("Exception inside castToAnotherType()");
        }
        return ret;
    }

    public static void main(String[] args) {
        try {
            String obj = MyClass.castToAnotherType(new Object());
        } catch (ClassCastException e) {
            System.out.print("Exception outside castToAnotherType()");
        }
    }

}
公共类MyClass{
公共静态T castToAnotherType(对象参数){
T ret=null;
试一试{
ret=(T)参数;
}catch(ClassCastException e){
System.out.print(“castToAnotherType()中的异常”);
}
返回ret;
}
公共静态void main(字符串[]args){
试一试{
字符串obj=MyClass.castToAnotherType(newobject());
}catch(ClassCastException e){
System.out.print(“castToAnotherType()之外的异常”);
}
}
}

结果是“castToAnotherType()之外的异常”。为什么在泛型方法内部没有发生异常?

由于编译器会删除泛型类型参数,因此方法内部的强制转换本质上等同于:

    Object ret = null;
    try {
        ret = (Object) param;
    } 
    ...
这不是问题,不管传递给方法的是什么(因为任何对象都可以转换为对象)


但是,当您尝试将该对象分配给字符串时,在main方法中,会出现
ClassCastException
,因为
Object
不能强制转换为
String

所有泛型类型都会在编译的代码中被删除。就编译后的代码而言,
casttoanother类型
只返回一个
对象
。但是,您的
main
方法尝试将其分配给
字符串
,而它不是
字符串
,因此会产生
ClassCastException


T
在编译过程中被有效擦除。见:

Java语言中引入了泛型以提供更紧密的类型 在编译时进行检查,以支持泛型编程。到 实现泛型,Java编译器将类型擦除应用于:

  • 将泛型类型中的所有类型参数替换为其边界或 对象,如果类型参数是无界的。产生的字节码, 因此,只包含普通类、接口和方法
  • 如有必要,插入类型强制转换以保持类型安全。生成 在扩展泛型类型中保留多态性的桥接方法
  • 类型擦除可确保不会为参数化类型创建新类 类型;因此,泛型不会产生运行时开销
因此,您的
castToAnotherType
T
擦除到ca中。以下内容:

public static Object castToAnotherType(Object param) {
    Object ret = null;
    try {
        ret = (Object) param;
    } catch (ClassCastException e) {
        System.out.print("Exception inside castToAnotherType()");
    }
    return ret;
}
public static void main(String[] args) {
    try {
        String obj = (String) MyClass.castToAnotherType(new Object());
    } catch (ClassCastException e) {
        System.out.print("Exception outside castToAnotherType()");
    }
}
这显然不会产生任何
ClassCastException

main(…)
是一个不同的故事,其结果如下:

public static Object castToAnotherType(Object param) {
    Object ret = null;
    try {
        ret = (Object) param;
    } catch (ClassCastException e) {
        System.out.print("Exception inside castToAnotherType()");
    }
    return ret;
}
public static void main(String[] args) {
    try {
        String obj = (String) MyClass.castToAnotherType(new Object());
    } catch (ClassCastException e) {
        System.out.print("Exception outside castToAnotherType()");
    }
}
当尝试将
对象
强制转换为
字符串
时,将生成
ClassCastException


请参阅的部分。

这是因为泛型类型擦除

       T ret = null;
       try {
            ret = (T) param;
...
由编译器翻译成

       Object ret = null;
       try {
            ret = (T) param;
...

这比我想象的要复杂得多。当我有时间的时候,我需要花更多的时间学习来充分理解这一点。现在,你有什么建议如何修复它吗?例如:如果无法将
param
转换为type
T
,则返回
null
?@Livy这是另一个问题,请单独提问。简而言之,其中一种方法是将
类targetClass
作为额外参数传递。但我希望看到其他答案。:)实际上
ret=(对象)参数。另请参见。