基于以下代码段:
// 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值并且只接受它吗?
答案 0 :(得分:3)
对于第一个问题:我期望转换为double
由编译器执行,但我不想在没有检查的情况下肯定地说。为清楚起见,我会使用后缀。 (如果我需要检查,这意味着维护代码的任何人都必须检查...为什么不只是使用正确类型的文字开头?)
12已解析为int
,而不是Integer
- 并且没有从int
到Double
的隐式转换。仅仅因为从int
到double
的隐式转换以及从double
到Double
的另一次转换并不意味着只有一个转换。
当然可以包括在内 - 但这意味着要让语言更加复杂,以获得相当小的收益。
答案 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)
int
{}未自动换行Double
但最重要的是 - 更喜欢原语和包装。
答案 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 的包装器)并且它们不一样。