when I use the IDE -"IDEA 14.03", it always give this notice for me. notice: 'StringBuilder sb' can be replaced with 'String'
Here is the details, when I define a object named "sb",and the object class is "StringBuilder". Here is code snippet that I tried:
StringBuilder sb = new StringBuilder("status=").append(status).append(" ,msg=").append(msg);
System.out.println(sb);
I just want to know what are the benefit if I change the "StringBuilder" to "String". And why the IDE always notify me to change the class type?
There is no such thing as a StringBuilder to String conversion. StringBuilder class provides you with a toString method which allows you to get the string which is actually stored in the internal buffer of the StringBuilder object. String s = sb.
When to use which one: If a string is going to remain constant throughout the program, then use String class object because a String object is immutable. If a string can change (example: lots of logic and operations in the construction of the string) then using a StringBuilder is the best option.
I think we should go with StringBuilder append approach. Reason being : The String concatenate will create a new string object each time (As String is immutable object) , so it will create 3 objects. With String builder only one object will created[StringBuilder is mutable] and the further string gets appended to it.
The Append method appends a string, a substring, a character array, a portion of a character array, a single character repeated multiple times, or the string representation of a primitive data type to a StringBuilder object.
I think in order to understand why your IDE tells you to change StringBuilder to String, you should understand the differences between String, StringBuffer and StringBuilder.
String is immutable. That means if you want to change something from the your string, the original string will not be deleted but created a new one, which includes your changes. StringBuffer and StringBuilder are mutable. That means with your changes, the original string will be changed accordingly.
The another main difference between them is that String and StringBuffer are thread-safe while StringBuilder is not. There are also other differences, please have a look at this site to learn more about the differences.
If you compare String with StringBuilder, on most cases, using String is more practical and logical, if you do not know, what you do with your string.
It is not always better to concatenate string with plus sign (+). For example, StringBuilder's append method is more logical if you change your string in a loop because of its mutability. Please read the comments in the code;
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.
}
What your IDE makes is just show you the best practices. That is why, it is called as recommendation.
If you want to go on your way anyway and do not want Intellij warn you about it; you can disable the warning like;
@CrazyCoder's comment is important to note here.
IDE is actually very smart here, it suggests you to change it for better code readability since internally compiler will generate exactly the same bytecode and your code will have the same performance and the same memory usage, but it will be easier to read. You get a readability benefit without any performance compromises. Similar question was asked and answered in IntelliJ IDEA forum some time ago.
Because code 1
String s1 = "a";
String s2 = "b";
String result = s1 + s2;
With code 2
String s1 = "a";
String s2 = "b";
String result = new StringBuilder().append(s1).append(s2).toString();
After being compiled into bytecode
, the results of the two pieces of code are the same. code 1
will be optimized to StringBuilder
in bytecode
by the compiler:
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
From the perspective of bytecode
, IDAE believes that these two writing methods are equivalent, and the writing method of code 1
is more concise. So it is recommended to use code 1
ps: If you don't like it, you can turn off this prompt :)
The above test is based on jdk1.8
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With