web-dev-qa-db-ja.com

奇妙なJavaキャスト例外。LongをFloatにキャストできないのはなぜですか?

LongをFloatにキャストできないのはなぜですか?

このエラーメッセージが表示されます:

Java.lang.ClassCastException:Java.lang.LongをJava.lang.Floatにキャストできません

なぜこれが問題なのですか?私がキャストしようとしている数値は、ドメイン[-10.0、10.0]の小数です。それらは、JFormattedTextField.getValue()を使用して返されるオブジェクトインスタンスとして始まります。ただし、フロートに変換する必要があります。

スタックトレース:

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)
15
CJJ

スタックトレースを提供すると役立ちます。

それ以外の場合、標準的な解決策は_(Float) someLongValue_をsomeLongValue.floatValue()に置き換えることです。

プリミティブ型を扱っている場合は、 5.1.2 Widening Primitive Conversion ですが、longからfloatにキャストできますが、精度が低下する可能性があるため、注意してください。明らかに、ラッパータイプ Long がありますが、これは暗黙的に変換できないため、classcastexceptionを取得します。これは、 autoboxing 、または明示的なLongオブジェクトの作成が原因である可能性があります。

さらにいくつかの招かれざるアドバイス:有効な値が-10から+10の範囲の小数である場合、標準のデータ型はint(プリミティブ)です。正確な数を意味する場合は、フロートを避けてください。 longも最適ではありません。これは、intのように完全にアトミックではなく、2倍のメモリを消費するためです。 「割り当てられていない」別の状態を許可する場合は、nullを取る可能性のあるIntegerも問題ありません。

16

例外は、LongとFloatに親子依存関係がないことをコンパイラーが認識するために発生します。オーバーロードされたキャスト演算子を見つけようとするC++とは異なります。

Numberから派生した任意のプリミティブラッパータイプでdoubleValue()を呼び出すことができるため、これが推奨される方法です。

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

ここで注意すべき点がいくつかあります。最初に、getValue()の出力をNumberにキャストしました。そうすれば、気が変わって、将来的に実際にDouble値を返すことができ、壊れることはありません。

また、floatではなくdouble値を使用しています。 JVMは内部でdoubleで動作するため、配列のスペースを節約する以外にfloatを使用する理由はありません。

10
kdgregory

基本的に、longからfloatへの変換は次のように簡単です。

_float f = (float)myLongVar;
_

JFormattedTextFieldの使用経験はありませんが、返されたオブジェクトをStringに型キャストし、.substring()を使用して正確な値を取得し、それをlongに型キャストすることができます。これは正しいアプローチではないかもしれませんが、問題を解決する可能性があります。

5
evilReiko

これを試して:

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

つまり、Longをプリミティブ(つまり非オブジェクト)型に変換する必要があります。

2
flybywire

JSONObjectをJava Objectに変換しているときに、この問題が発生しました。コードを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を実行する必要はありませんが、私はクリーンであるために実行するのが好きです:)。

すでに長い値(またはintなど)がある場合は、String.valueOf(myInt)を使用して文字列を取得します。

お役に立てれば、

-アンドリュー

0
Android334

Float/doubleのマシンビット表現をバイトに変換したり、バイトから変換したりする場合は、 Double.doubleToLongBits および Float.floatToIntBits および関連する関数を参照してください。

0
Jason S