Java 如何预防;通知:' ;;StringBuilder sb';可替换为';字符串'&引用;在intellij思想中

Java 如何预防;通知:' ;;StringBuilder sb';可替换为';字符串'&引用;在intellij思想中,java,intellij-idea,Java,Intellij Idea,当我使用IDE-“IDEA 14.03”时,它总是为我发出此通知。注意:“StringBuilder sb”可以替换为“String” 下面是详细信息,当我定义一个名为“sb”的对象时,对象类是“StringBuilder”。以下是我尝试过的代码片段: StringBuilder sb = new StringBuilder("status=").append(status).append(" ,msg=").append(msg); System.out.println(sb); 我只是想知

当我使用IDE-“IDEA 14.03”时,它总是为我发出此通知。注意:“StringBuilder sb”可以替换为“String”

下面是详细信息,当我定义一个名为“sb”的对象时,对象类是“StringBuilder”。以下是我尝试过的代码片段:

StringBuilder sb = new StringBuilder("status=").append(status).append(" ,msg=").append(msg);
System.out.println(sb);

我只是想知道如果我将“StringBuilder”更改为“String”,有什么好处。为什么IDE总是通知我更改类类型?

我认为为了理解IDE为什么告诉您将StringBuilder更改为String,您应该理解String、StringBuffer和StringBuilder之间的区别

字符串是不可变的。这意味着,如果要更改字符串中的某些内容,则不会删除原始字符串,而是创建一个新字符串,其中包括您所做的更改。StringBuffer和StringBuilder是可变的。这意味着您的更改将相应地更改原始字符串

它们之间的另一个主要区别是String和StringBuffer是线程安全的,而StringBuilder不是。还有其他的差异,请看一看,了解更多的差异

如果您将字符串与StringBuilder进行比较,在大多数情况下,如果您不知道如何使用字符串,则使用字符串更实用、更符合逻辑

用加号(+)连接字符串并不总是更好。例如,如果由于字符串的易变性而在循环中更改字符串,则StringBuilder的append方法更符合逻辑。请阅读代码中的注释

String a;
StringBuilder b;
for(int i=0; i<5; i++)
{
a += i; //String is immutable and in each iteration, a new object will be created
b.append(i); //StringBuilder is mutable and in each iteration, the existing string will be used.
}
字符串a;
StringBuilder b;

对于(int i=0;i我知道这是一个老问题,已经有了很好的答案,但只是一个小小的无关评论: 在这种情况下,为了可读性,(而且由于编译器的操作与Ad提到的相同),我将使用String.format。 而不是

StringBuilder sb = new StringBuilder("status=").append(status).append(" ,msg=").append(msg);
我觉得这更具可读性:

String.format("status=%s, msg=%s", status, msg);

虽然使用字符串连接更容易阅读代码,但对于Java 8及以下版本,这是通过StringBuilder实现的,因此表面上看,这似乎是在伤害自己

但是,StringBuilder的默认容量为16。如果深入研究StringBuilder的源代码,您将看到realloc使用:

         int newCapacity = (value.length << 1) + 2;
您已经为自己保存了3个alloc和数组副本

据我所知,Java 9+有一个更好的解决方案。因此,知道这一问题会得到解决,我通常使用字符串,除非我知道性能是一个问题,然后我恢复了StringBuilder。如果你在嵌入式系统或Android上工作,因为资源稀缺。在云服务器上,情况肯定会如此

至于IntelliJ inspector,我关闭了它,但我通常会在注释中添加JAVA10标记,这样我可以在以后找到它们,并在迁移到10时恢复它们。也许,我只需要记住重新启用inspector即可。:)

PS-我喜欢Udi的答案。我将调查实施情况

为什么IDE总是通知我更改类类型

Java8:代码的效果相同,但字符串串联

String r = s1 + s2;

更具可读性,因为代码1

String s1 = "a";
String s2 = "b";
String result = s1 + s2;
使用
代码2

String s1 = "a";
String s2 = "b";
String result = new StringBuilder().append(s1).append(s2).toString();
编译成字节码后,两段代码的结果是相同的<编译器将在
bytecode
中的
StringBuilder
中优化代码>代码1

   L0
    LINENUMBER 15 L0
    LDC "a"
    ASTORE 1
   L1
    LINENUMBER 16 L1
    LDC "b"
    ASTORE 2
   L2
    LINENUMBER 17 L2
    NEW java/lang/StringBuilder
    DUP
    INVOKESPECIAL java/lang/StringBuilder.<init> ()V
    ALOAD 1
    INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
    ALOAD 2
    INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
    INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;
    ASTORE 3
   L3
    LINENUMBER 18 L3
    RETURN
   L4
    LOCALVARIABLE args [Ljava/lang/String; L0 L4 0
    LOCALVARIABLE s1 Ljava/lang/String; L1 L4 1
    LOCALVARIABLE s2 Ljava/lang/String; L2 L4 2
    LOCALVARIABLE result Ljava/lang/String; L3 L4 3
    MAXSTACK = 2
    MAXLOCALS = 4
L0
线路号15 L0
最不发达国家“a”
阿斯托尔1号
L1
行号16 L1
最不发达国家“b”
阿斯托尔2号
L2
行号17 L2
新java/lang/StringBuilder
重复
调用特别的java/lang/StringBuilder。()V
阿洛德1号
invokeVirtualJava/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;
阿洛德2号
invokeVirtualJava/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;
invokeVirtualJava/lang/StringBuilder.toString()Ljava/lang/String;
阿斯托尔3号
L3
线路号18 L3
返回
L4
LOCALVARIABLE args[Ljava/lang/String;L0 L4 0
LOCALVARIABLE s1 Ljava/lang/String;L1 L4 1
LOCALVARIABLE s2 Ljava/lang/String;L2 L4 2
LOCALVARIABLE结果Ljava/lang/String;L3 L4 3
MAXSTACK=2
最大局部数=4
bytecode
的角度来看,IDAE认为这两种书写方法是等价的,
code 1
的书写方法更简洁,建议使用
code 1

String s1 = "a";
String s2 = "b";
String result = s1 + s2;
ps:如果您不喜欢,可以关闭此提示:)


上面的测试是基于jdk1.8的,它说可以用字符串连接来替换字符串生成器代码(
string r=s1+s2;
)在不影响代码的情况下,因为您在构建字符串时没有条件。感谢您的回答,我仍然有一个疑问,如果我接受这个想法给出的想法是否有任何好处?或者它与我编写的代码的效果相同。如果在串联过程中没有条件,则不会有任何区别。如果您ave,那么字符串生成器稍微好一点,但总的来说,这可能也没什么大不了的。我想知道你为什么忽略IDEA添加的解释。它告诉你为什么它建议进行此更改。你还没有解释IDEA建议使用字符串连接的原因(您的答案仅假设这将导致额外的4个子字符串,这些子字符串不需要,只意味着更多内存)而不是手动使用StringBuilder。@Tom我不想用填鸭式输入OP。我已经试着向他展示了如何获得答案,如果他想在研究后禁用此选项,我已经展示了如何禁用它。我认为此答案回答了他的两个问题。不过,我将添加更多链接,以简化他的学习过程。好吧,那就把你不完整的答案称为“not spoon feed OP”,不管怎样。但我想知道为什么你添加了不相关的信息,比如im-/易变性或线程安全性,尽管它是obivou