使用Class.cast时无法将java.lang.Float强制转换为浮点型?

问题描述:

我已经有一个解决方案,但我不喜欢它。此外,很高兴知道你对此的看法。使用Class.cast时无法将java.lang.Float强制转换为浮点型?

你会看到,elem.get给出了Object,这在x和y的情况下将是Float

此代码抛出在标题中描述的例外:

String names[] = { "x", "y", "src" }; 
Class types[] = { float.class, float.class, String.class }; 

for (int i = 0; i < names.length; i++) 
{ 
    if (elem.containsKey(names[i])) 
    { 
     par.add(types[i]); 
     arg.add(types[i].cast(elem.get(names[i]))); 
    } 
} 

的代码被用于定义参数列表实例化对象。参数和对象的类名都是在外部数据文件中定义的(但对此不会有所了解)。

的解决方案,一些我不喜欢的(因为它失去了灵活性,我试图获得),具有此范围内的为:

if(types[i] == float.class) 
{ 
    float v = (Float)elem.get(names[i]); 
    arg.add(v); 
} else 
{ 
    arg.add(types[i].cast(elem.get(names[i]))); 
    break; 
} 

其他选项将在types被改变float.classFloat.class ,但我不会这样做,因为该代码用于实例化在其构造函数中具有参数float的对象。

谢谢!

+0

如果您使用的是Java 1.5或更高版本,则Floats会被自动取消装箱以浮动,否?你有没有尝试使用Float.class? – Spektr

+0

正如我写的,我不想使用Float.class,因为我需要将参数用作实例后面的float。但是如果我在这段代码中使用Float.class,它就可以工作。它试图实例化构造函数浮动的Object时会失败。感谢您的回答! – huff

+0

顺便说一句,我与Java 1.7。 – huff

由于args类型是ArrayList<Object>,你不回避拳击反正:

// This code... 
float v = (Float)elem.get(names[i]); 
arg.add(v); 

// Will actually be equivalent to: 
float v = (Float)elem.get(names[i]); 
Float boxed = v; 
arg.add(boxed); 

如果该点是通过反射来调用构造函数,那么你要已经到通过Float任何float参数 - 这就是它的工作原理。

因此,基本上,将float.class更改为Float.class,它应该都可以正常工作。编辑:啊,除了那么par列表将有错误的类型。基本上你想要Float.class,但添加float.class到参数类型的列表。

你可能想从原始类型的地图包装类,像这样:

private static final Map<Class<?>>, Class<?>> PRIMITIVE_TYPE_MAP = 
    buildPrimitiveTypeMap(); 

private static Map<Class<?>>, Class<?>> buildPrimitiveTypeMap() 
{ 
    Map<Class<?>>, Class<?>> map = new HashMap<Class<?>>, Class<?>>(); 
    map.put(float.class, Float.class); 
    map.put(double.class, Double.class); 
    // etc 
    return map; 
} 

然后:

String names[] = { "x", "y", "src" }; 
Class types[] = { float.class, float.class, String.class }; 

for (int i = 0; i < names.length; i++) 
{ 
    if (elem.containsKey(names[i])) 
    { 
     par.add(types[i]); 

     // For primitive types, only box to the wrapper type 
     Class<?> castType = PRIMITIVE_TYPE_MAP.get(types[i]); 
     if (castType == null) 
     { 
      castType = types[i]; 
     } 
     arg.add(castType.cast(elem.get(names[i]))); 
    } 
} 

事实上,如果你相信的值的我怀疑你可以这样做:

arg.add(elem.get(names[i])); 

毕竟,你只是投射到一个特定的类型,然后再次丢失该类型的信息...使用cast调用确实执行时间类型是正确的,所以你可能想保留它原因。

+0

糟糕。抱歉。 arg是ArrayList 。 – huff

+0

@huff:对,就像我想的那样 - 当你为它添加一个“float”时,无论如何它都会被装箱到“Float”。将编辑我的答案,使更清晰。 –

+0

谢谢!所以,但是当我使用Float.class时,它找不到要实例化的对象的正确构造函数。 – huff