Java中的双倍与双倍[重复]
Posted
技术标签:
【中文标题】Java中的双倍与双倍[重复]【英文标题】:Double vs double in java [duplicate] 【发布时间】:2012-10-31 04:27:49 【问题描述】:可能重复:Java : different double and Double in comparison
在我的一个实验室的示例 java 程序中,我有两种不同的方法,分别采用 Double 和 double 参数。 向它们传递参数时如何区分它们?
【问题讨论】:
顺便说一句,除了参数之外,这些方法具有相同的签名。 相关:different double and Double in comparison 你为什么不显示你的代码? 这是他们给我们的一个存根类。所以,它真的没什么,但它在这里: 对不起,我是新手。如何在此处粘贴我的代码? 【参考方案1】:Double
参数可以是null
而double
不能。
【讨论】:
不,我的问题是我想调用这些方法。所以,当我向他们传递论据时,我不知道它会传给哪一个。一个接受double的还是接受Double的? @Mahmoud 是的,原始双打通常是最好的。 @Andrew 在这种情况下我不能。这是实验室说明的一部分。 @Mahmoud 取决于参数的静态类型。如果它是原始类型,它将转换为double
并使用原始类型调用重载。如果参数的静态类型是类Double
,那么它会调用装箱类型的重载。【参考方案2】:
首先,您需要了解这两种类型之间的区别。
double
是原始类型,而 Double
是 Object。
下面的代码显示了一个重载的方法,我假设它类似于您的实验室代码。
void doStuff(Double d) System.out.println("Object call");
void doStuff(double d) System.out.println("Primitive call");
您可以通过多种方式调用这些方法:
doStuff(100);
doStuff(200d);
doStuff(new Double(100));
这些调用将导致:
"Primitive call"
"Primitive call"
"Object call"
【讨论】:
非常感谢。这很有帮助。根本不知道200d。 我发现以下信息在理解差异时更有用:double 是 double 类型的简单数字。双倍是一类。它包含一个 double 类型的字段,但具有 .toString() 和 floatValue() 等内置函数,并且可以扩展。使用 'double' 你需要 String.valueOf() 来获取它的字符串,但是使用 Double 你可以只使用 .toString()。 什么时候用第一个,什么时候用后者?【参考方案3】:- double
是一个原始类型,而Double
是一个包装对象。
- Wrapper 对象最常见的用途之一是使用Collection
。
例如:
List<Double> d = new ArrayList<Double>();
-在Java 5中引入了一种称为Autoboxing
的机制来在两者之间直接进行转换。
例如:
double d = 10.41;
Double wrapper = d;
【讨论】:
包装器对象不与泛型一起使用,它们在泛型之前用于将原始类型存储在集合中。它们还用于需要可空类型的其他上下文中。 (特别是在做 ORM 时的实体 ID。)【参考方案4】:Double
是引用类型,double
是值类型。
Double
类将原始类型 double 的值包装在对象中。 Double 类型的对象包含一个类型为 double 的字段。" link
正如@Fess 提到的,因为Double
是引用类型,所以它可以是null
。
如果您愿意,可以使用.doubleValue()
方法将Double
显式转换为double
,反之亦然使用new Double(1.0)
。
正如@millimoose 所说:
您应该使用
X.valueOf()
而不是new X()
。valueOf
方法允许缓存装箱类型以减少内存使用。 (不确定这是否适用于Double
s,但这是一个养成的好习惯。)"
【讨论】:
您几乎不需要再进行这种显式转换了。自动装箱将根据上下文为您插入对doubleValue
和 valueOf
的调用。
是的,我知道。我将答案更改为“如果您想要...”。这和***.com/questions/12846624/…几乎是一样的问题
另外我认为你应该使用X.valueOf()
而不是new X()
。 valueOf
方法允许缓存装箱类型以减少内存使用。 (不确定这是为Double
s 做的,但这是一个好习惯。)
是的,我写的很快,我没有说。我将编辑我的答案并将您之前的评论引用到最后【参考方案5】:
// Method A
public static void foo(Double d) ...
// Method B
public static void foo(double d) ...
显然,如果你传递一个Double
对象,那么方法A 将被调用;即,如果你有类似的东西:
Double d = new Double(1.0);
此外,如果您传递一个双字面值,您将调用 方法 B。有趣的是,如果你有类似的东西
double d = new Double(1.0);
在这种情况下方法B也会被调用,因为d
的类型是double
; Double
对象被拆箱为 double
。同样,如果您有:
Double d = 1.0;
然后将调用 方法 A,因为 d
的类型将是 Double
(double
-literal 自动装箱为 Double
)。
【讨论】:
重要的一点是,如果您需要进行这种区分,这可能是代码异味。理想情况下,其中一个重载应该环绕另一个。 (事实上,在任何一组重载中,大多数可能最终都应该委托给其中一个或单个私有实现方法。) "double d= new Double(1.0)" 不是子类/超类问题。 “d 是 Double 的实例化”是不正确的。它不是 Double 的实例化。您正在创建一个 Object Double,然后将其拆箱成一个 double。本质上这是一个无用的声明。 "然后方法 A 将被调用,因为 d 的类型将是双精度(而不是双精度)" - 仍然是错误的。d
将是 Double
,因为 这就是你声明它的方式。
自动装箱不允许变量同时具有两种类型,或者与声明的类型不同。编译器所做的只是自动插入装箱和拆箱代码。这意味着double d1 = new Double(1.0);
被编译为double d1 = new Double(1.0).doubleValue();
。相反,Double d2 = 1.0;
被编译为Double d2 = Double.valueOf(1.0);
。 在任何时候都是d1
类型为Double
,或d2
类型为double
。
@millimoose 谢谢 - 这是一个错字。【参考方案6】:
您所拥有的是method overloading 的示例。好的部分是编译器和 JVM 将根据您调用方法时使用的参数类型自动选择正确的方法。
【讨论】:
【参考方案7】:Double 是一个包装类,而 double 是像 c/c++ 这样的原始类型。如上所述,Double 主要用于泛型,但在需要数值和适当的对象封装的任何地方也很有用。在大多数情况下,Double 和 double 可以互换使用。
【讨论】:
以上是关于Java中的双倍与双倍[重复]的主要内容,如果未能解决你的问题,请参考以下文章
CocoaTouch (iPhone) 中的双倍行距文本视图