简体   繁体   中英

Strange Java cast exception. Why can't I cast Long to a Float?

Why can't I cast Long to a Float?

I get this error message:

java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Float

Why is this a problem? The numbers that I'm trying to cast are decimals in the domain [-10.0, 10.0]. They start out as Object instances returned using JFormattedTextField.getValue() . But they must be converted to floats.

Stack trace:

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)

It would help if you provide a stacktrace.

Otherwise, the standard solution is to replace (Float) someLongValue with someLongValue.floatValue()

If you are dealing with primitive types, you can just cast from long to float, although it is a 5.1.2 Widening Primitive Conversion , but one that may lose precision, so be careful! Obviously you have the wrapper type Long , which cannot implicitly be converted, thus you get the classcastexception. This may be because of autoboxing , or explicit Long object creation.

Some more uninvited advice: if your valid values are decimals in the range of -10 to +10 the standard data type is int (primitive). avoid float if you mean exact numbers. long is also not optimal, because it is not fully atomic like int and it takes 2x the memory. If you allow a different state "not assigned" then Integer , which may take null, is also OK.

The exception happens because the compiler recognizes that Long and Float do not have a parent-child dependency. Unlike C++, which will try to find an overloaded cast operator.

You can call doubleValue() on any of the primitive wrapper types that are derived from Number, so this is the recommended way to do what you want:

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

A couple of things to note here: first, I casted the output of getValue() to Number. That way, you can change your mind and actually return Double values in the future, and you won't break.

Also, I'm using double values, not float. The JVM works with double internally, so there's no reason to use float except to save space in an array.

Basically, converting long to float is as easy as this:

float f = (float)myLongVar;

I have no experience in using JFormattedTextField , but you can try type-casting the returned object to String, use .substring() to get the exact value, and type-cast it to long. This may not be the right approach, but it may solve your problem.

try this:

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

ie, you have to transform your Long to a primitive (ie non-object) type.

如果要将float / double的机器位表示转换为/从字节转换,请参阅Double.doubleToLongBitsFloat.floatToIntBits及相关函数。

I had this problem when I was converting a JSONObject to a Java Object. I had to change my code from double a = (double) json.get("myJSONKey"); to the following:

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

Note you don't have to do the try/catch but I like to just so I'm clean :).

In the event you already have a long value (or int or whatever) then use String.valueOf(myInt) to get your string.

Hope this helps,

-Andrew

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM