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 参数可以是nulldouble 不能。

【讨论】:

不,我的问题是我想调用这些方法。所以,当我向他们传递论据时,我不知道它会传给哪一个。一个接受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 方法允许缓存装箱类型以减少内存使用。 (不确定这是否适用于Doubles,但这是一个养成的好习惯。)"

【讨论】:

您几乎不需要再进行这种显式转换了。自动装箱将根据上下文为您插入对 doubleValuevalueOf 的调用。 是的,我知道。我将答案更改为“如果您想要...”。这和***.com/questions/12846624/…几乎是一样的问题 另外我认为你应该使用X.valueOf() 而不是new X()valueOf 方法允许缓存装箱类型以减少内存使用。 (不确定这是为Doubles 做的,但这是一个好习惯。) 是的,我写的很快,我没有说。我将编辑我的答案并将您之前的评论引用到最后【参考方案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类型doubleDouble 对象被拆箱为 double。同样,如果您有:

Double d = 1.0;

然后将调用 方法 A,因为 d 的类型将是 Doubledouble-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) 中的双倍行距文本视图

Xcode Playground 中的 ViewController - 帧报告双倍大小 (viewDidLoad)

选择 SQL 查询时出现双倍结果 [重复]

将字符串反序列化为双倍[重复]

C# 中的双倍比较精度损失,加减双精度时发生精度损失

错误 0x1c8250:iphone 中的双倍可用内存