I often saw people saying
String str = new String("my string") is less efficient than writing
String str = "my string", because the former creates a static “my string” object and then new’s a String object that gets copied from the static one.
However, given that the language here is so simple and unambiguous, I can hardly imagine that Java optimizer won’t take any effort to simply convert the former to the latter. Why would it really choose to do it the more laborious way? What can any negative side effects be if Java does optimize it?
However, given that the language here is so simple and unambiguous, I can hardly imagine that Java optimizer won’t take any effort to simply convert the former to the latter.
First, you shouldn’t write code saying to do something slow just because you think the compiler will replace it with something faster.
Second, the compiler can’t generally optimize this, because
new guarantees the creation of a new object. If you do
String str = new String("my string");
then it’s guaranteed that
str != "my string". Java can only optimize out the
new if it can prove that the String object’s identity won’t matter to the execution of the program.
Have a look into the generated bytecode for
String s1 = "1":
LDC "1" ASTORE 1
String s2 = new String("2"):
NEW java/lang/String DUP LDC "2" INVOKESPECIAL java/lang/String.<init> (Ljava/lang/String;)V ASTORE 2
The latter example is redundant and more complicated. Compiler won’t make any optimizations in this case. It is guaranteed that a new instance of a String class will be created.
String str = "my string" the JVM can reuse instance of a String instead of creating a new one. Consider next examples:
String s1 = "1"; String s2 = "1"; System.out.println(s1 == s2); // true => same reference, s1 & s2 point to the same object String s3 = "1"; String s4 = new String("1"); System.out.println(s3 == s4); // false => s3 & s4 point to different objects
You should always write the simplest, clearest code you can. Developer efficiency is more important than processor efficiency 90+% of the time. So even if the JIT could optimise it, which it doesn’t, you are placing a burden on the developer to work out; why is this code more complicated than it needs to be? and the hardest answer to find is; no good reason at all.
Why would it really choose to do it the more laborious way?
When people migrate from other languages like C++ they take their idioms with them. In C++ for example you would need to write
new string("some text") but in Java this is needlessly redundant.
What can any negative side effects be if Java does optimize it?
Java can optimise it with escape analysis. If the String doesn’t escape the current method after inlining, the
new String can be places on the stack and thus eliminated as it’s redundant. But that is beside the point. You have already made life harder for anyone who has to maintain the code and the JIT won’t help you with that.
It’s not an issue of performance. It’s just doing something in an unnecessarily complicated way. Unless you’re working with interned
Strings to do comparisons with
==, the code will work the same way too.
Java won’t optimize anything because there’s nothing to optimize. If you use String literals, identical ones are reduced to the same instance in the string pool, so
String foo = "foo"; String bar = "foo"; System.out.println(foo == bar); // True, the same object
However with the explicit constructor
String foo = "foo"; String bar = new String("foo"); System.out.println(foo == bar); // False, bar is explicitly created as a new object with the constructor
However as you still should use
equals() for all object comparisons, you won’t see any difference while running your code.