【问题标题】:Java: many ways of casting a (long) Object to doubleJava:将(长)对象转换为双精度的多种方法
【发布时间】:2012-12-13 08:26:44
【问题描述】:

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

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

double x = (double)obj;

或者我应该先将其转换为 long 然后再转换为 double。

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's answer 的讨论。

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

【问题讨论】:

  • “我有一个Object obj,我知道它实际上是一个long”。不可能。
  • 我的原始代码是double x = (double)(long)obj;,它似乎工作正常。我还没有尝试过其他版本。我只是想知道什么是最好的方法,因为双重演员对我来说似乎没有必要。我现在知道我的 Object 实际上是 Number 这就是演员不会失败的原因。
  • 请不要发布额外的parseDouble 答案。无用的解析只会扼杀性能。

标签: java casting numbers double long-integer


【解决方案1】:

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

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

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

if(object instanceof Number) ...

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

【讨论】:

  • 我最喜欢这个答案。它简要解释了拳击,我通过调试器尝试了object instanceof Number 测试,以查看我的 JVM 中发生了什么。谢谢!
【解决方案2】:

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

不,你没有。 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();

【讨论】:

    【解决方案3】:

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

    double d = (double)15234451L;
    

    【讨论】:

    • 嗯,他说他有一个“对象”,所以没有原始的long 可以转换为“双”。
    【解决方案4】:

    您可以将其转换为Long(因为Object不是long 而是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);
        }
    }
    

    【讨论】:

    • 您只需要一个演员表:double d = (Long) obj;double d = (long) obj;
    • @assylias:我更喜欢清晰,因为不管我写与否,演员都在那里。 (当然,在上面,我确实需要两个强制转换。如果我分配给一个变量,我只能依赖隐式强制转换。)另外,double d = (long)obj; 失败,你不能将Object 转换为long
    • Object o = 15L; double d = (long) o; 编译运行无异常。
    • @assylias:关于什么?在 Oracle 的 JDK 1.6 上不适合我:pastie.org/5519551
    • @Juve:必须是 Java 7 增强版。
    【解决方案5】:

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

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

    【讨论】:

    • "Long => double is not" 对我有用,大概是 Long 自动拆箱。
    • Object o = 5L; double d = (double) o; 不起作用。但是double d = (Long) o; 可以。 ;-)
    • @assylias:我从没说过。 :-) 我说 Long => double works。确实如此,请看我的回答。
    猜你喜欢
    • 2011-03-11
    • 2015-06-12
    • 2011-11-20
    • 2015-11-24
    • 2015-02-12
    • 1970-01-01
    • 1970-01-01
    • 2015-05-17
    • 1970-01-01
    相关资源
    最近更新 更多