【问题标题】:Strange Java cast exception. Why can't I cast Long to a Float?奇怪的 Java 强制转换异常。为什么我不能将 Long 转换为 Float?
【发布时间】:2010-12-11 22:12:00
【问题描述】:

为什么我不能将 Long 转换为 Float?

我收到此错误消息:

java.lang.ClassCastException: java.lang.Long 无法转换为 java.lang.Float

为什么会出现这个问题?我试图转换的数字是域 [-10.0, 10.0] 中的小数。它们从使用 JFormattedTextField.getValue() 返回的 Object 实例开始。但它们必须转换为浮点数。

堆栈跟踪:

Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Float
    at submodeler.animation.Timeline.setKeyedAttribute(Timeline.java:59)
    at submodeler.ui.attributes.TransformationAttributePanel.actionPerformed(TransformationAttributePanel.java:247)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2028)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2351)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
    at java.awt.Component.processMouseEvent(Component.java:6348)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
    at java.awt.Component.processEvent(Component.java:6113)
    at java.awt.Container.processEvent(Container.java:2085)
    at java.awt.Component.dispatchEventImpl(Component.java:4714)
    at java.awt.Container.dispatchEventImpl(Container.java:2143)
    at java.awt.Component.dispatchEvent(Component.java:4544)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4618)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4282)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4212)
    at java.awt.Container.dispatchEventImpl(Container.java:2129)
    at java.awt.Window.dispatchEventImpl(Window.java:2475)
    at java.awt.Component.dispatchEvent(Component.java:4544)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:635)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

【问题讨论】:

  • 最终提供 Timeline.java:59 周围的源代码以找到解决方案。
  • 这是时间轴中发生的事情: public void setKeyedAttribute(int position, String property, Object value){ lastIndex = addKeyFrameAt(position); keyframes.get(lastIndex).setAttribute(property, value);但是,现在我已将其更改为 value 输入参数需要浮点类型。这(结合 kdgregory 的回应)解决了这个问题。谢谢!

标签: java casting


【解决方案1】:

我在将 JSONObject 转换为 Java 对象时遇到了这个问题。我不得不将我的代码从 double a = (double) json.get("myJSONKey"); 更改为以下内容:

try {
  double a = Double.parseDouble((String) myJSONObject.get("myJSONKey"));
} catch(NumberFormatException e)
{
  System.err.out("I could not convert it to a double!! :(");
}

请注意,您不必执行 try/catch,但我喜欢这样做,这样我就干净了 :)。

如果您已经有一个 long 值(或 int 或其他),请使用 String.valueOf(myInt) 获取您的字符串。

希望这会有所帮助,

-安德鲁

【讨论】:

  • 在查看了更多内容后,如果您已经拥有原始数据类型,@Andreas 的答案会更精通性能,因为字符串是内存猪。
【解决方案2】:

基本上,将 long 转换为 float 就这么简单:

float f = (float)myLongVar;

我没有使用JFormattedTextField 的经验,但是您可以尝试将返回的对象类型转换为字符串,使用.substring() 获取确切的值,然后将其类型转换为long。这可能不是正确的方法,但它可能会解决您的问题。

【讨论】:

    【解决方案3】:

    如果你提供一个堆栈跟踪会有所帮助。

    否则,标准解决方案是将(Float) someLongValue替换为someLongValue.floatValue()

    如果你正在处理原始类型,你可以从 long 转换为 float,虽然它是 5.1.2 Widening Primitive Conversion,但可能会丢失精度,所以要小心!显然你有包装类型Long,它不能被隐式转换,因此你得到了classcastexception。这可能是因为autoboxing,或显式 Long 对象创建。

    更多不请自来的建议:如果您的有效值是 -10 到 +10 范围内的小数,则标准数据类型为 int(原始)。如果您的意思是确切的数字,请避免浮动。 long 也不是最优的,因为它不像 int 那样完全是原子的,它需要 2 倍的内存。如果您允许不同的状态“未分配”,那么Integer(可能为空)也可以。

    【讨论】:

    • 基本上就是这样,你不能对两个不兼容的类进行类型转换。自动装箱不会发挥它的魔力来拆箱号码,然后将其装箱为另一个号码。您绝对需要从中获取价值,我建议您执行以下操作:Float.valueOf(long.floatValue());.
    • 如果启用自动装箱,Float.valueOf(long.floatValue()) 和 long.floatValue() 应该一样好。
    • 我忘记了自动装箱的细节,但如果是这样:“new Float(long.floatValue())”而不是“Float.valueOf(long.floatValue())”,那么前者将消耗比需要更多的内存。但是他们真的很接近。
    • 看一下java.lang.Float的源码(1.6第404行): public static Float valueOf(float f) { return new Float(f); }
    • @Malaxeur - 自动装箱是否等同于“new Float(long.floatValue())”或“Float.valueOf(long.floatValue())”是特定于实现的,但与@Andreas一样指出,这对于 Java 1.6 来说是没有意义的。对于其他类型(例如 Integer),它没有实际意义,但 Java 1.6 编译器会在这种情况下生成对 Integer.valueOf 的调用。
    【解决方案4】:

    发生异常是因为编译器识别出 Long 和 Float 没有父子依赖关系。与 C++ 不同,C++ 会尝试查找重载的强制转换运算符。

    您可以在派生自 Number 的任何原始包装类型上调用 doubleValue(),因此这是执行您想要的操作的推荐方法:

    double val = ((Number)textField.getValue()).doubleValue()
    

    这里有几点需要注意:首先,我将 getValue() 的输出转换为 Number。这样一来,您就可以改变主意并在以后实际返回 Double 值,而不会中断。

    另外,我使用的是双精度值,而不是浮点数。 JVM 在内部使用双精度,因此没有理由使用浮点数,除非是为了节省数组空间。

    【讨论】:

      【解决方案5】:

      如果您希望将浮点/双精度的机器位表示转换为字节,请参阅Double.doubleToLongBitsFloat.floatToIntBits 以及相关函数。

      【讨论】:

        【解决方案6】:

        试试这个:

        Long l = ...
        Float f = new Float ((float)l.longValue());
        

        也就是说,您必须将 Long 转换为原始(即非对象)类型。

        【讨论】:

        • 我先尝试了这个。它抛出了相同的强制转换异常。它直接来自 JFormattedTextField。所以我不能先“创建”一个 Long 。我什至将 JFormattedTextField 的值设置为浮点值。
        猜你喜欢
        • 1970-01-01
        • 2015-12-15
        • 1970-01-01
        • 2017-11-26
        • 1970-01-01
        • 2012-03-06
        • 1970-01-01
        • 1970-01-01
        • 2010-10-10
        相关资源
        最近更新 更多