web-dev-qa-db-ja.com

Java :(長い)オブジェクトをdoubleにキャストする多くの方法

_Object obj_があり、実際にはlongであることがわかっています。一部の数学コードでは、doubleとして必要です。

直接2倍にキャストしても大丈夫ですか?

_double x = (double)obj;
_

それとも、最初にロングにキャストしてから、ダブルにキャストする必要があります。

_double x = (double)(long)obj;
_

私はまた別の(読みにくい)代替案を見つけました:

_double x = new Long((long)obj).doubleValue();
_

どちらかを行うことの危険性/影響は何ですか?

ソリューションの概要

  • objNumberであり、longではありません。
  • Java 6では、明示的なキャストが必要です。例:double x = ((Number)obj).doubleValue()
  • Java 7には機能するキャストマジックがあります:double x = (long)obj

Java6/7の問題の詳細については、 TJの回答 の説明も参照してください。

編集:いくつかの簡単なテストを行いました。キャストの両方の方法(明示的/魔法)は同じパフォーマンスを持っています。

10
Juve

Javaのすべてのプリミティブ番号は、オブジェクトが必要なときにそのボックス型にキャストされ(この場合はLong)、すべてのボックス番号はNumberのインスタンスであるため、これを行う最も安全な方法は次のとおりです。

final Object object = 0xdeadbeefL;
final double d = ((Number)object).doubleValue();

ここでの危険は、いつものように、キャストしたいObjectNumber型ではないことです。この場合、ClassCastExceptionを取得します。次のようなオブジェクトのタイプを確認できます

if(object instanceof Number) ...

クラスキャストの例外を防ぎ、代わりに0.0のようなデフォルト値を指定する場合。また、黙って失敗する方法は必ずしも良い考えではありません。

10
Neet

私は実際にはlongであることがわかっているObject objを持っています。

いいえ、しません。 longはプリミティブデータ型であり、Javaのプリミティブ型はオブジェクトではありません。プリミティブ型longJava.lang.Longには違いがあることに注意してください。ラッパークラス。

Long(オブジェクト)をlong(プリミティブ)にキャストすることはできません。 longからLong値を取得するには、その上でlongValue()を呼び出します。

Long obj = ...;

long value = obj.longValue();

doubleに直接キャストしても安全ですか?

それが実際にプリミティブlongである場合、はい、それをdoubleにキャストできます。 Longオブジェクトの場合、キャストする必要はありません。doubleValue()を呼び出すだけです。

double x = obj.doubleValue();
7
Jesper

ObjectからLongまたはlongへのキャストが1つだけ必要です(暗黙的にLongにキャストしてから、ボックス化解除を適用します)。

Object o = 5L;
double d = (long) o; //Apparently only works on Java 7+
//or
double d = (Long) o;
0
assylias

単純なキャストは完全にうまくいくはずです。これは、ラッパークラスを経由して、文字列表現を取得してからdoubleに解析し、long値を使用して新しいインスタンスを再度作成するよりも高速です。さらに重要なことに、より読みやすくなります。

double d = (double)15234451L;
0
Rahul

それをLongにキャストして(ObjectnotlongであるがLongであるため)、キャストすることができますLongからdoubleへ:

double d = (double)(Long)obj;

たとえば、これは2.6666666666666665の期待される出力を持っています:

public class CastDouble {
    public static final void main(String[] args) {
        Object o = 15L;

        System.out.println(40 / (double)(Long)o);
    }
}
0
T.J. Crowder