方法从FindBugs调用效率低的new String()构造函数

时间:2019-04-06 00:20:17

标签: java encoding netbeans-8

谢谢您的帮助,因为我对编码还很陌生,并且只是根据到目前为止所学的内容来测试一些新代码。

    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()”

3 个答案:

答案 0 :(得分:2)

基本上有3种编写代码的方式:

您的版本:

String x = new String();

FindBugs

推荐的版本 1
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();'只是看它如何与我的整个代码一起工作。

再次感谢,感谢您的回复!