在下面的程序中,我无法理解为什么ClassCastException
int.class
更新
我应该指定我知道原始类型是什么。 What I don't understand is why int.class is provided with broken implementation?
public static void main(String[] args) {
System.out.println(DataType.INT.getValue(Integer.class));
System.out.println(DataType.INT.getValue(int.class));//Class cast exception here
}
enum DataType {
INT {
@Override
public <T> T getValue(Class<T> toClass) {
return toClass.cast(1000);//ClassCastException here for int.class
}
};
public abstract <T> T getValue(Class<T> toClass);
}
答案 0 :(得分:3)
好的,经过一些链接,并尝试了一些代码,我发现: -
int.class
== Integer.TYPE
== int int.class
!= Integer.class
因此,int.class
的值是表示类型int
的Class对象。
因此,当您使用DataType.INT
调用int.class
时,toClass
包含int
,您无法调用cast
。可能是因为它没有从Object
类延伸。因为cast
方法在内部使用isinstance
来检查调用类型是否为Object
类型。
public T cast(Object obj) {
if (obj != null && !isInstance(obj))
throw new ClassCastException();
return (T) obj;
}
因此,如果调用cast
的类型不是Object
的实例,当然primitive
类型不是,它将返回false
,因此ClassCastException
。
答案 1 :(得分:3)
这是因为cast()
的{{1}}操作使用isInstance() Class
。
如果此Class对象表示基本类型,则此方法返回false。
method which returns false for primitive classes
方法的代码低于
cast()
答案 2 :(得分:0)
Integer
是int
值的类包装器,而int
是基本类型,而不是类。不要在原始类型和类之间混淆,例如,在必须使用类时在代码中混淆:
List<int> lstInteger; //won't compile!
List<Integer> lstInteger; //compiles fine
更多信息:
将int
类型视为原始C / C ++ int类型。知道这一点,int不是一个类,因此没有任何属性,任何方法,只是持有一个整数值。另一方面,java.lang.Integer
是int
基元类型的类包装器。这是为了在只能使用对象实例的情况下使用int
。一个很好的例子是Java中的通用系统,它只适用于类(如代码示例中所提出的)。
有关详细信息,请参阅Oracle Java教程:Primitive Data Types。
答案 3 :(得分:0)
我认为这是因为int.class
与Integer.class
不同。
<强>更新强>
我们可以查看cast方法,它的参数是Object
,所以很明显1000得到了自动装箱,因此该方法的实际参数是Integer
的实例:
public T cast(Object obj) {
if (obj != null && !isInstance(obj))
throw new ClassCastException();
return (T) obj;
}
答案 4 :(得分:0)
当您尝试将一种数据类型的Object转换为另一种数据类型时,Java会抛出类强制转换异常。这里int不是一个Object,它是一个在运行时由一些本机代码实例化的原语。
答案 5 :(得分:0)
我认为这就是发生的事情:
当您致电return toClass.cast(1000);
时,文字1000
将升级为Integer
。这里提到了促销规则:Java Language Specification。
现在,在cast
上调用intClass
方法时,它会检查参数(1000)是否属于同一个实例,即int.class
,并且由于其不存在而失败。
另一方面,当您转换为Integer.class
时,它会成功,因为实例类型匹配。
因为文字ClassCastException
Promotion
1000
Integer
,{{1}}即将到来。