CJJ
CJJ

Reputation: 358

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)

Upvotes: 16

Views: 51853

Answers (6)

acrawly
acrawly

Reputation: 453

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

Upvotes: 0

evilReiko
evilReiko

Reputation: 20473

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.

Upvotes: 6

Andreas Petersson
Andreas Petersson

Reputation: 16518

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.

Upvotes: 17

kdgregory
kdgregory

Reputation: 39606

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.

Upvotes: 10

Jason S
Jason S

Reputation: 189686

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

Upvotes: 0

flybywire
flybywire

Reputation: 273572

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.

Upvotes: 2

Related Questions