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

时间:2012-10-21 05:36:19

标签: java generics

在下面的程序中,我无法理解为什么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);

}

6 个答案:

答案 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)

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

List<int> lstInteger; //won't compile!
List<Integer> lstInteger; //compiles fine

更多信息:


int类型视为原始C / C ++ int类型。知道这一点,int不是一个类,因此没有任何属性,任何方法,只是持有一个整数值。另一方面,java.lang.Integerint基元类型的类包装器。这是为了在只能使用对象实例的情况下使用int。一个很好的例子是Java中的通用系统,它只适用于类(如代码示例中所提出的)。

有关详细信息,请参阅Oracle Java教程:Primitive Data Types

答案 3 :(得分:0)

我认为这是因为int.classInteger.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}}即将到来。