为什么我会为int.class强制转换获得类强制转换exception

在下面的程序中,我无法理解为什么从int.classClassCastException

更新:我应该指定我知道原始类型是什么。 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.INTint.classtoClass 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; 

Integerint值的类包装器,而int是基本类型,而不是类。 不要在原始类型和类之间混淆,例如,在必须使用类时在代码中:

 List lstInteger; //won't compile! List lstInteger; //compiles fine 

更多信息:

  • Java:int与Integer
  • Java:int或整数

int类型视为原始C / C ++ int类型。 知道这一点,int不是一个类,因此没有任何属性,任何方法,只是持有一个整数值。 另一方面, java.lang.Integerint基本类型的类包装器。 这是为了在只能使用对象实例的情况下使用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.classInteger.class

更新


我们可以看一下cast方法,它的参数是一个Object所以很明显1000得到了自动装箱,因此该方法的实际参数是Integer一个实例:

 public T cast(Object obj) { if (obj != null && !isInstance(obj)) throw new ClassCastException(); return (T) obj; }