Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java cannot cast from boxed type to primitive type

Tags:

java

I am trying to use Class.cast () to convert a boxed Double to the primitive 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);

I am doing this because in some part of my code, a value object and a Class are given dynamically, and I do have the guarantee that the value object is of the compatible type. But this exception really confuses me. What is the contract of using cast () ?

UPDATE I ran into this because we have code like:

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;
  }
}

If double and Double are so different that they are not considered assignable in neither ways, why java allow the getClazz () method in the DoubleProvider to compile? What is the relation between double.class and Double.class?

like image 758
Xinchao Avatar asked Dec 03 '25 17:12

Xinchao


1 Answers

You can't cast a Double to a double (or vice versa) since neither is a subtype of the other. Use (double) which auto-unboxes the value instead.

What is the contract of using cast()?

The javadoc for the API is the contract of the method. In this case javadoc says:

Casts an object to the class or interface represented by this Class object.

[...]

Throws: ClassCastException - if the object is not null and is not assignable to the type T.

If you need to get the primitive (unboxed) version of an Object based on the Class, I see no better way than

if (clazz == double.class)
    handleDouble((double) o);
if (clazz == int.class)
    handleInt((int) o);
...

Regarding your edit: This is because double.class has the type Class<Double>. The JLS states:

The type of p.class, where p is the name of a primitive type (§4.2), is Class<B>, where B is the type of an expression of type p after boxing conversion (§5.1.7).

like image 122
aioobe Avatar answered Dec 06 '25 08:12

aioobe