2

Possible Duplicate:
Java Strings: “String s = new String(”silly“);”
What is the purpose of the expression “new String(…)” in Java?

There are two ways to create a String object:

1) using literal as in String s ="hello" (creates one object)
2) using new as in String s = new String("hello") (creates two objects)

I was wondering why do ever I need to go for 2) approach?

Community
  • 1
  • 1
Anand
  • 20,708
  • 48
  • 131
  • 198
  • Interestingly, the .Net team agreed with you: there's no `String` constructor that accepts another `String` object. – dlev Apr 12 '12 at 19:05
  • You need to go with approach 2 when you want your String objects to be created in the heap and want them to be garbage collected quickly. When you create String's using literals they are created in PermGen and are Garbage collected only when the class is unloaded. – Geek Jul 17 '13 at 06:01

5 Answers5

12

If you create a string with new, then you get a different String reference. This can avoid creepy behaviour:

String s = "hello";
String t = "hello";
String u = new String("hello");
System.out.println(s==t);
System.out.println(t==u);

prints true, false. I can't really think of a real bit of software where I'd use this. But in a sense it is 'safer' to create new references, so that == doesn't surprise us.

Richante
  • 4,353
  • 19
  • 23
  • Do you use the second approach in your programs? – Eugene Retunsky Apr 12 '12 at 19:07
  • 1
    Here is a more serious example: suppose you have a `substring` of a really large string. Doing `new String(hugeString.substring(0, 10))` prevents you from retaining a reference to that huge string and allows it to be garbage collected. That's a genuinely real-world-appropriate case. – Louis Wasserman Apr 12 '12 at 19:20
4

The basic difference between them is memory allocation.

First option i.e

String s1 = "hello";

When you use this s1 is called as a string literal and memory for s1 is allocated at compile time.

But in 2nd case

String s2 = new String("hello");

In this case s2 is called as an object of String representing hello

When you tries to create two string literal using the first case, only one memory is referenced by those two literals. I mean String literals are working with a concept of string pool. when you create a 2nd string literal with same content, instead of allocating a new space compiler will return the same reference. Hence you will get true when you compare those two literals using == operator.

But in the 2nd case each time JVM will create a new object for each. and you have to compare their contents using equals() method but not with == operator.

If you want to create a new string object using 2nd case and also you don't want a new object, then you can use intern() method to get the same object.

String s = "hello";
String s1 = new String("hello").intern();
System.out.println(s == s1);

In this case instead of creating a new object, JVM will return the same reference s. So the output will be true

Chandra Sekhar
  • 18,914
  • 16
  • 84
  • 125
  • This is not what is expected of the question. When String pool is more memory efficient, then why do we need to use new keyword and create more memory.? – KnockingHeads May 07 '21 at 08:04
1

The second approach is just a possibility. Actually is never used (by most of developers). The first one is a less and more convenient version of the latter, no reasons to use the second way.

PS. The second just creates a different link to the literal. Technically they will re-use the same char array. The only difference is the reference will be different (i.e. == will give false, but NEVER use == for string comparison).

Eugene Retunsky
  • 13,009
  • 4
  • 52
  • 55
  • But I have read that creating String object using new creates two objects, one object will be created using new and second one using String literal.. – Anand Apr 12 '12 at 19:09
  • It will create another reference to the string literal. Technically they will re-use the same char array. The only difference is the reference will be different (i.e. == will give false, but NEVER use == for string comparison). – Eugene Retunsky Apr 12 '12 at 19:14
1

The only mentally sane occasion where new String("foo") should be used are unit-tests. You can make sure that the code does not use == for string comparisons but the proper .equals() method.

A.H.
  • 63,967
  • 15
  • 92
  • 126
  • What about `Object lock1 = new String ( "Lock" ) ; Object lock2 = new String ( "Lock" ) ; ... synchronized ( lock1 ) { ... }`? Not really a strong case, but I think it is also a sane usage of `new String("foo")`. – emory Apr 12 '12 at 19:15
  • 1
    @emory:I don't think so, because `new Object()` does the same job with less noise and without the "why did he use a string for that?` much later. – A.H. Apr 12 '12 at 19:17
0

This can be understood as a constructor per copy. They are very used in C++. The net effect is having a duplicate of the object passed as a parameter, in this case, a String.

Caumons
  • 9,341
  • 14
  • 68
  • 82