我对Java编程相对较新,并且在面向对象方面有一个小问题。所以,让我们开始吧!我最近写了一个程序来查找 0 和数字 x 之间的所有素数,其中"i"是素数。在此程序中,其中两行与以下内容相同。
BigInteger one = BigInteger.valueOf(i);
one = one.nextProbablePrime();
这些行的目的是将整数 i 转换为 BigInteger,以便使用下一个 ProbablePrime 方法。回顾这一点,我发现我没有使用关键字"new",因此没有创建 BigInteger 类的实例,但程序仍然编译并运行顺利。如果没有创建 BigInteger 类的实例,为什么程序能够使用 nextProbablePrime 方法、编译和运行?此外,在其他情况下以及与其他类和方法一起不创建对象是否有效。另外,它是否会阻止我使用 BigInteger 类的全部功能,它是否被认为是良好的编程实践?
我还把上面的两行代码重写成两行代码,程序的其余部分保持不变。
BigInteger one = new BigInteger(String.valueOf(i));
one = one.nextProbablePrime();
我更改了两者的第一行,以包括"新"一词的使用。正如我所料,它运行没有缺陷。回到我的其他问题,哪一个更好?尽管我使用的是类或方法,但哪一个会给我带来最大的功能,哪一个更被认为是好的做法?
综上所述,我的问题是:1. 哪一个是正确的?2. 无论我使用什么类或方法,哪一个都能在所有情况下工作?3. 哪一个被认为是良好的编程实践?4. 第一个如何在不创建对象的情况下工作?
Biginteger类的快速链接,对于那些可能想看它的人 - 这里
您确实创建了BigInteger
类的实例。 只是 new
关键字在 BigInteger.valueOf
方法的实现中的某个地方使用。
BigInteger.valueOf
通常更有效率。 它可以对某些i
值重用相同的BigInteger
对象 - 也许是0,或者可能像Integer.valueOf(int)
,它从-128到128。
BigInteger.valueOf
称为工厂方法,经常推荐使用。 除此之外,工厂方法可以有名称,而构造函数不能;他们对实施有更多的控制权;有很多很好的理由。 事实上,Effective Java中的第一个建议是"考虑静态工厂方法而不是构造函数"。
如果你实际查找BigInteger.valueOf
的源代码,你可以看到这就是它正在做的事情:它检查它是否可以重用一个常量值 - ZERO
或一个小的正值或负值 - 如果失败,它只是继续调用new BigInteger(value)
,尽管它使用接受long
的内部私有构造函数而不是使用String.valueOf
。
第一种方法使用 BigInteger 中的静态方法。这将是我的偏好,尽管两者都有效并且都做完全相同的事情。
new
关键字在内存中创建对象的实际实例。由于BigInteger.valueOf(i);
方法是静态的,因此它不需要 BigInteger 的实例(此方法本身将为您创建一个新的 BigInteger(。
如果您查看文档:
公共静态 BigInteger valueOf(long val(
返回一个 BigInteger,其值等于指定的值 长。这种"静态工厂方法"优先于 (long(构造函数,因为它允许重用常用的 大整数。
参数: val - 要返回的 BigInteger 的值。返回: 具有指定值的大整数。
您正在调用的方法正在返回 BigInteger 的新实例
这里: http://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html
你在这里处理的是 BigInteger 类的静态方法。
此方法将返回自动分配的 BigInteger 实例,这就是 Louis 正确的原因。 new
在valueOf
方法中为您所用。
首先,对象是在内部创建的(*可能并不总是如此(。
拥有valueOf()
方法的原因之一是有可能将BigInteger缓存在某个小范围内,以免浪费资源。(创建 1 个值为 5 的对象,而不是大量对象(。
调用new
时必须创建对象,但您可以在方法内部的 if 语句中重用旧对象
两种变体都可以。但最好使用valueOf
因为
- 不要创建不必要的字符串。
- 有可能
要回答您的所有问题:
-
两者都是 100% 正确的。
-
两者都可以在任何合理的情况下工作。
-
第一种方法的开销(滞后(可能最少。
-
第一种方法确实会在您调用的函数中创建一个对象,如下所示:
public static BigInteger valueOf(long val( { BigInteger bigInteger = new BigInteger((; 做一些事情使val变成一个BigInteger 返回 bigInteger;}
因此,当它回到您的变量时,它已经使用了 new
关键字。