为什么我会为int.class强制转换获得类强制转换exception
在下面的程序中,我无法理解为什么从int.class
为ClassCastException
更新:我应该指定我知道原始类型是什么。 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 getValue(Class toClass) { return toClass.cast(1000);//ClassCastException here for int.class } }; public abstract T getValue(Class toClass); }
好的,经过一些链接,并尝试了一些代码,我发现: –
-
int.class
==Integer.TYPE
== int -
int.class
!=Integer.class
因此, int.class
的值是表示int
类型的Class对象。
因此,当您使用int.class
调用DataType.INT
, int.class
会toClass
int
,您无法在其上调用toClass
。 可能是因为它没有从Object
类扩展。 因为, cast
方法在内部使用isinstance
来检查调用类型是否是Object
类型。
public T cast(Object obj) { if (obj != null && !isInstance(obj)) throw new ClassCastException(); return (T) obj; }
因此,如果调用强制转换的类型不是Object
的实例,当然primitive
类型不是,它将返回false
,因此返回ClassCastException
。
发生这种情况是因为Class
cast()
操作使用isInstance() method which returns false for primitive classes
。
如果此Class对象表示基本类型,则此方法返回false。
cast()
方法的代码如下
public T cast(Object obj) { if (obj != null && !isInstance(obj))//It fails here since isInstance returns false throw new ClassCastException(); return (T) obj;
Integer
是int
值的类包装器,而int
是基本类型,而不是类。 不要在原始类型和类之间混淆,例如,在必须使用类时在代码中:
List lstInteger; //won't compile! List lstInteger; //compiles fine
更多信息:
- Java:int与Integer
- Java:int或整数
将int
类型视为原始C / C ++ int类型。 知道这一点,int不是一个类,因此没有任何属性,任何方法,只是持有一个整数值。 另一方面, java.lang.Integer
是int
基本类型的类包装器。 这是为了在只能使用对象实例的情况下使用int
。 一个很好的例子是Java中的通用系统,它只适用于类(如代码示例中所提出的)。
有关详细信息,请参阅Oracle Java教程: 原始数据类型 。
当您尝试将一种数据类型的Object转换为另一种数据类型时,Java会抛出类强制转换exception。 这里int不是Object,它是一个在运行时由一些本机代码实例化的原语。
我想这就是发生的事情:
当你调用return toClass.cast(1000);
,文字1000
正在升级为Integer
。 这里提到了促销规则: Java语言规范 。
现在,当在intClass
上调用cast
方法时,它检查参数(1000)是否是同一个实例,即int.class
并且它因为不是而失败。
另一方面,当您转换为Integer.class
,它会成功,因为实例类型匹配。
因此, ClassCastException
即将推出,因为将文字1000
提升为Integer
。
我认为这是因为int.class
与Integer.class
。
更新
我们可以看一下cast方法,它的参数是一个Object
所以很明显1000得到了自动装箱,因此该方法的实际参数是Integer
一个实例:
public T cast(Object obj) { if (obj != null && !isInstance(obj)) throw new ClassCastException(); return (T) obj; }