显式类型转换vs使用后缀为float / double Java - 区别?

时间:2012-01-04 17:31:56

标签: java

基于以下代码段:

    // as primitive
    MyClass.primitiveMethod(double val); // method signature
    MyClass.primitiveMethod(12);         // ok

    // as object
    MyClass.objectMethod(Double val); // method signature
    MyClass.objectMethod(12);         // error
    MyClass.objectMethod(12d);        // ok
    MyClass.objectMethod((double)12); //ok

Q1:虽然12d(double)12似乎都有效,但是在指定后缀和显式转换之间有什么区别吗? (行为/性能)

Q2:为什么MyClass.objectMethod(12)必须被视为错误?虽然12应该被解析为Integer对象,但Java不能足够聪明地知道12也是值Double值并且只接受它吗?

6 个答案:

答案 0 :(得分:3)

对于第一个问题:我期望转换为double由编译器执行,但我不想在没有检查的情况下肯定地说。为清楚起见,我会使用后缀。 (如果我需要检查,这意味着维护代码的任何人都必须检查...为什么不只是使用正确类型的文字开头?)

12已解析为int,而不是Integer - 并且没有从intDouble的隐式转换。仅仅因为从intdouble的隐式转换以及从doubleDouble的另一次转换并不意味着只有一个转换。

当然可以包括在内 - 但这意味着要让语言更加复杂,以获得相当小的收益。

答案 1 :(得分:2)

坦率地说,我从不使用12d。为了清楚地说明一个数字是双数,我使用12.0。对于花车,您必须说12.0f

这是打字的一个额外角色,但我发现它是迄今为止最“自然”的角色。 YMMV。

ADDED

至于你的实际问题,往返包装器的自动装箱原语会产生意想不到的结果,(这对Java Puzzlers书来说是一个很大的好处!)而且我更愿意尽可能地避免它。如果方法需要Double,在调用代码中我通常会明确地将其设为

objectMethod(Double.valueOf(12.0));

虽然不得不承认,对于相对较小的东西来说,这是很多打字!然而,当de-autoboxing(比方说,该方法返回一个Double)我几乎总是说

double d = result.doubleValue();

并且值得,因为它提醒您结果是一个Object而可能是null 。当你得到一些无法解释的NPE时,比方说,该方法返回null,因为没有连接FooBarServer,这将帮助你实现正在发生的事情。或者,更好的是,提醒原始代码首先测试一个空结果!

答案 2 :(得分:0)

  1. 使用后缀(文字)
  2. 可能是,但似乎并非如此。 int {}未自动换行Double
  3. 但最重要的是 - 更喜欢原语和包装。

答案 3 :(得分:0)

A1:不,在编译完成后,它们的结果都是一样的。

A2:int原语被自动装箱到Integer个对象。请参阅Java语言规范5.1.7 Boxing Conversion。您是否愿意Java猜到了您的意思并为您更改了Object类?不,程序员告诉机器该做什么而不是机器猜测程序员的意图要好得多。

答案 4 :(得分:0)

'12d'是双字面的。 '(double)12'是对int literal的操作。你不能保证后者会优化前者,而不是它可能有所作为。正确输入的文字更清晰,更自我记录,所以使用它。为什么要指定不必要的转换?

答案 5 :(得分:0)

对于第一个问题,请使用后缀, 12d 更简洁明了。

对于第二个...说12你正在使用 int 原语并使用 Double 你正在谈论一个对象 double 的包装器)并且它们不一样。