tags:

views:

747

answers:

5

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)

+1  A: 

try this:

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

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

flybywire
I tried this first. It threw the same cast exception. It comes directly from JFormattedTextField. So I cannot 'create' a Long first. I'm even setting values to the JFormattedTextField as Float values.
CJJ
+5  A: 

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 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.

Andreas Petersson
It's basically that, you can't typecast two incompatible classes. Autoboxing does NOT work its magic to unbox the number and then box it as the other number. You absolutely need to get the value from it and I'd recommend doing something like: Float.valueOf(long.floatValue());.
Malaxeur
if autoboxing is enabled, Float.valueOf(long.floatValue()) and just long.floatValue() should be equally good.
Andreas Petersson
I forget the specifics of autoboxing, but if it does: "new Float(long.floatValue())" instead of "Float.valueOf(long.floatValue())" then the former will consume more memory than needed. However they're really close.
Malaxeur
take a look at the source of java.lang.Float (line 404 in 1.6): public static Float valueOf(float f) { return new Float(f); }
Andreas Petersson
@Malaxeur - it is implementation specific whether autoboxing will be equivalent to "new Float(long.floatValue())" or "Float.valueOf(long.floatValue())", but as @Andreas points out, this is moot for Java 1.6. For other types (e.g. Integer) it is not moot, but the Java 1.6 compiler generates calls to Integer.valueOf in that case.
Stephen C
A: 

If you are looking to convert machine bit-representations of float/double to/from bytes, see Double.doubleToLongBits and Float.floatToIntBits and associated functions.

Jason S
+2  A: 

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.

kdgregory
This works very well. Thanks!
CJJ
A: 

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, then use .substring() to get the exact value, then type-cast it to long. this could be not the right approach, but may solve your problem

evilReiko