-3

I have seen most of times developer declares the string in below fashion

Approach 1:-

public void method1(){
String str1 ="Test";

}

Approach 2:-

Per my understanding better approach will be

public void method2(){
String str2 = new String("Test");

}

Again based on my understanding , Second approach is better than first, because String literal are interned and stored in permgen. So it will not be GC'ed even thread comes out of approach 1 but in second approach str2 will be GC'ed(Str 2 will not be interned) as thread comes out of method 2 and GC runs as it is stored in heap not permgen.

Is my understanding correct ?

Per mine understanding I should literal if same string is going to be created again and again as it will be good for performance point of view otherwise go for new String() so that can be GC'ed once not used ?

Linked related string-literal-String-Object

  • 6
    I'm confused. What do you think the "Test" your second example is, if it's not a literal? – Kilian Foth Jan 17 '18 at 8:38
  • I'm frankly not familiar with this difference of treatment by the GC, but even if this were true, you probably should not be worrying about how the compiler is optimizing, at least not at that level. If you want to provide hints to the garbage collector, use WeakReference and SoftReference. – Neil Jan 17 '18 at 8:44
  • 3
    Initializes a newly created String object so that it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of the argument string. Unless an explicit copy of original is needed, use of this constructor is unnecessary since Strings are immutable. String. Now the question is when a copy is necessary if any change on it generates a new one that doesn't modify the original? Or does it creates the same sequence of chars in memory? – Laiv Jan 17 '18 at 8:49
  • @KilianFoth Per my understanding when we create String with equal operator like String str1 ="Test" then only intern method is called and stored intern perm gen space, But when we create string with new operator like String str2 = new String("Test") intern method is not called and new object is created which is stored in heap(not in perm gen) – scott miles Jan 17 '18 at 12:02
  • It is not an equal operator, but a string literal. – mid Jan 17 '18 at 15:15
5

In both your examples you have string literal "Test" and in 2) you have another string literal "new". During runtime you create another string with content of "Test" from the string literal "Test" and then create new one containg "Testnew".

In modern Java there is no good reason to use new String(someString);

In older version there was one. String.substring used to create string that was referencing original string and with offset and length restricting it to the vanted value. Therefore if you had long string and created short substring from him, forgot all references to the long one and kept the substring you still had one reference in the substring to the original long string. Therefore the long string would not get GCed. If you used substring = new String(substring), you created separate instance without reference to the original.

Therefore if you target older java platforms, you still should consider using the new String(substring) approach (consider, not just use it!!! You need to identify whether default behavior is problem first).

This change happened between JDK 6 and 7. viz article on programcreek

  • Per my understanding when we create String with equal operator like String str1 ="Test" then only intern method is called and stored intern perm gen space, But when we create string with new operator like String str2 = new String("Test") intern method is not called and new object is created which is stored in heap(not in perm gen). So I am bit confused when your statement In both your examples you have string literal "Test" – scott miles Jan 17 '18 at 12:06
  • See stackoverflow.com/questions/3297867/… where discussion says String str = "abc" is called string literal but new String("test") – scott miles Jan 17 '18 at 12:10
  • 2
    @scottmiles - the point is that the "Test" that is created in order to pass as an argument to the String constructor (i.e. the one inside the brackets) is still a string literal and all the same rules apply; it is interned, and it is preallocated when the class initializes. So all your suggestion does is create a second copy that is subject to garbage collection, without removing the original that isn't. – Jules Jan 17 '18 at 12:55
  • So most of times its better to use without new operator – scott miles Jan 17 '18 at 13:50
  • Yes. New operator make sense if you are creating string from byte array, character arrays or something like that (there are multiple constructors). – user470365 Jan 17 '18 at 14:42

Not the answer you're looking for? Browse other questions tagged or ask your own question.