Java无法从盒装类型转换为基本类型

Xin*_*hao 2 java

我试图使用Class.cast()将盒装Double转换为原始double:

Object d = 1.0d;
Class<?> clazz = double.class;
//the bellow line throws java.lang.ClassCastException: 
//Cannot cast java.lang.Double to double
clazz.cast(d);
Run Code Online (Sandbox Code Playgroud)

我这样做是因为在我的代码的某些部分,动态地给出了一个值对象和一个类,并且我确实保证值对象是兼容类型.但是这个例外让我很困惑.使用cast()的合同是什么?

更新我遇到了这个,因为我们的代码如下:

interface Provider <T> {
  T get ();
  Class<T> getClazz();
}

//a special handling for double primitive
class DoubleProvider implements Provider<Double> {

  public double getDouble(){
      return 1.0d;
  }

  @Override
  public Double get() {
    return getDouble();
  }

  @Override
  public Class<Double> getClazz() {
    //why this actually compiles?
    return double.class;
  }
}
Run Code Online (Sandbox Code Playgroud)

如果double和Double是如此不同以至于它们都不被认为是可分配的,为什么java允许DoubleProvider中的getClazz()方法进行编译?double.class和Double.class之间的关系是什么?

aio*_*obe 6

您不能 a转换Double为a double(反之亦然),因为它们都不是另一个的子类型.使用(double)自动取消装箱的值.

什么是使用合同cast()

API的javadoc是方法的契约.在这种情况下,javadoc说:

将对象强制转换为此Class对象所表示的类或接口.

[...]

抛出: ClassCastException - 如果对象不为null并且不能赋值给类型T.

如果你需要根据类获得Object的原始(未装箱)版本,我认为没有比这更好的方法了

if (clazz == double.class)
    handleDouble((double) o);
if (clazz == int.class)
    handleInt((int) o);
...
Run Code Online (Sandbox Code Playgroud)

关于你的编辑:这是因为double.class有类型Class<Double>.该JLS状态:

类型p.class,其中p是基本类型的名称(§4.2)Class<B>,其中B是拳击转换后类型p的表达式的类型(第5.1.7节).