10

我有一个Object obj我知道实际上是一个long. 在一些数学代码中,我需要它作为double.

直接将其转换为双倍是否安全?

double x = (double)obj;

或者我应该先把它投长,然后加倍。

double x = (double)(long)obj;

我还找到了另一个(可读性较差)替代方案:

double x = new Long((long)obj).doubleValue();

这样做有什么危险/影响?

解决方案总结

  • obj是一个Number而不是一个long
  • Java 6 需要显式转换,例如:double x = ((Number)obj).doubleValue()
  • Java 7 具有有效的演员阵容:double x = (long)obj

有关 Java6/7 问题的更多详细信息,还请阅读TJ 答案的讨论。

编辑:我做了一些快速测试。两种投射方式(显式/魔术)具有相同的性能。

4

5 回答 5

10

当需要一个对象时(在我们的例子中),Java 中的每个原始数字都被强制转换为它的装箱类型,并且每个装箱的数字都是这样做的最安全方法的Long一个实例:Number

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

与往常一样,这里的危险是,Object我们想要转换的类型不是类型Number,在这种情况下你会得到一个ClassCastException. 您可以检查对象的类型,例如

if(object instanceof Number) ...

如果您想防止类转换异常,而是提供一个默认值,例如0.0. 同样,默默失败的方法并不总是一个好主意。

于 2012-12-13T08:47:38.783 回答
7

我有一个Object obj我知道实际上是一个long.

不,你没有。long是原始数据类型,Java 中的原始类型不是对象。long请注意,原始类型和之间存在差异java.lang.Long,后者是一个包装类。

您不能将Long(对象)转换为long(原始)。要从 a 中获取longLong,请调用longValue()它:

Long obj = ...;

long value = obj.longValue();

直接将其转换为安全double吗?

如果它实际上是一个原始的long,那么是的,你可以将它转换为一个double. 如果它是一个Long对象,你不需要强制转换,你可以调用doubleValue()它:

double x = obj.doubleValue();
于 2012-12-13T08:33:33.697 回答
0

您可以将其转换为 a Long(因为Objectis不是along而是 a Long),然后将其Long转换为 a 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);
    }
}
于 2012-12-13T08:33:57.977 回答
0

您只需要一次转换,从 Object 到 Long 或 long (隐式转换为 Long 然后应用拆箱):

Object o = 5L;
double d = (long) o; //Apparently only works on Java 7+
//or
double d = (Long) o;
于 2012-12-13T08:32:22.497 回答
0

简单的铸造应该可以很好地工作。这将比通过包装类、获取字符串表示然后解析为 double、使用 long 值再次创建新实例更快——更重要的是,它更具可读性。

double d = (double)15234451L;
于 2012-12-13T08:32:29.363 回答