5

在下面的程序中,我不明白为什么会有ClassCastExceptionfor cast fromint.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);

}
4

6 回答 6

3

发生这种情况是因为使用isInstance()cast()的操作。Class 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;
于 2012-10-21T06:13:48.723 回答
3

好的,在浏览了一些链接并尝试了一些代码之后,我发现:-

  • int.class== Integer.TYPE== 整数
  • int.class!=Integer.class

因此, 的值int.class是表示类型的 Class 对象int

所以,当你调用你的DataType.INTwith时,你不能调用int.classtoClasscontainsts 。可能是因为它没有从类扩展。因为,方法内部用于检查调用类型是否为类型。intcastObjectcastisinstanceObject

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

因此,如果调用的类型cast不是 的实例Object,当然primitive类型不是,它将返回false,因此返回 a ClassCastException

于 2012-10-21T05:37:30.687 回答
0

当您尝试将一种数据类型的对象转换为另一种数据类型时,Java 会引发类转换异常。这里 int 不是一个对象,它是一个在运行时由一些本机代码实例化的原语。

于 2012-10-21T05:56:04.240 回答
0

我认为这是正在发生的事情:

当你打电话return toClass.cast(1000);时,字面1000量被提升为Integer。此处提到了提升规则:Java 语言规范

现在,当cast方法被调用时intClass,它会检查 argument(1000) 是否属于同一实例int.class,即它是否失败,因为它不是。

另一方面,当您转换为 时Integer.class,它是成功的,因为实例类型确实匹配。

所以 theClassCastException来是因为Promotion字面意思1000to Integer

于 2012-10-21T06:24:34.823 回答
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 教程:原始数据类型

于 2012-10-21T05:37:27.097 回答
0

我认为这是因为它int.classInteger.class.

更新


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

public T cast(Object obj) {
if (obj != null && !isInstance(obj))
    throw new ClassCastException();
return (T) obj;
}
于 2012-10-21T05:46:55.943 回答