谢谢您的帮助,因为我对编码还很陌生,并且只是根据到目前为止所学的内容来测试一些新代码。
public static void main(String[] args) {
// TODO code application logic here
String x = new String();
String y = new String();
int x1;
int y1;
System.out.println("Welcome");
System.out.println("Enter x prediction");
Scanner scanstr = new Scanner (System.in);
Scanner scanint = new Scanner (System.in);
x = scanstr.nextLine();
System.out.println("Enter y prediction");
y = scanstr.nextLine();
当我针对此代码运行FindBugs时,我得到了(对于字符串“ x”和“ y”):
“方法调用效率低的新String()构造函数 使用无参数构造函数创建新的java.lang.String对象会浪费内存,因为这样创建的对象在功能上将与空字符串常量“”无法区分。 Java保证相同的字符串常量将由相同的String对象表示。因此,您应该直接使用空字符串常量。”
我知道我可以直接将x声明为“ String x”,而无需使用“ new String()”,但是还有其他方法可以优化代码而又无需摆脱“ new String()”
答案 0 :(得分:2)
基本上有3种编写代码的方式:
您的版本:
String x = new String();
FindBugs
String x = "";
最有效的版本 2 :
String x; // No initialization is needed when the first thing we will do
// with 'x' is to assign a (real) value to it
您还可以移动声明,以便可以将最后一个版本写为:
String x = scanner.nextLine();
其他版本很可能是第一版的衍生版本,效率甚至更低。 (他们可能会阻止FindBugs
进行投诉,但这不是一个好主意。)
还有没有其他方法可以优化代码而又不放弃'new String()'
不。见上文。
FindBugs
提出的观点是使用String()
构造函数效率低下,并且在几乎所有情况下都没有必要。
这也可能效率低下,并且(IMO)绝对不利于可读性,从而不必要地初始化局部变量。但是,new String()
的成本远远大于不必要的初始化的成本。
(唯一需要使用new String()
的情况是,您的应用程序被故意实现为依赖于String
对象标识(例如,您正在使用==
来比较字符串)并且您需要有多个不同的String
实例,它们是“长度为零的字符串”。我很难想到要在实际应用中执行的操作。)
1-FindBugs是推荐的替代方法。做某事并不是在“告诉你”。您应该记住,诸如FindBugs之类的工具中的建议通常基于简单的启发式方法,并不总是最佳的解决方案。
2-我应该对此进行限定。 JIT编译器可能甚至可能会注意到此初始化是不必要的,并且不会发出任何本机代码指令来执行此操作。这将使辩论变得毫无意义。实际上,JIT编译器甚至有可能对第一个版本执行类似的优化...,因为它可能知道String()
构造函数没有副作用。但是请注意,这些优化仅适用于不需要初始化的情况。不允许JIT编译器将new String()
优化为""
...,因为它们实际上是不同的意思。
答案 1 :(得分:0)
错误消息告诉您要这样做:
String x = "";
String y = "";
原因是Java承诺任何空字符串文字(""
)都由内存中的同一String
对象表示,并且由于String
是不可变的,因此没有理由有单独的实例。
您的代码与上面的代码段之间的区别在于,上面的代码段不会创建其他String
对象,而您的代码段会创建两个新的String
对象,这些对象之后会立即被丢弃。
答案 2 :(得分:0)
感谢大家的答复和澄清。我更改了代码“字符串x;”。在运行FindBugs以阻止它抱怨之后,并想确保它是有效的。我还将尝试'String x = Scanner.nextLine();'只是看它如何与我的整个代码一起工作。
再次感谢,感谢您的回复!