3
public String makinStrings() {
   String m = "Fred47";
   String s = "Fred";
   s = s + "47";
   s = s.substring(0);
   return s.toString();
} 

How many objects are created by the code?

I made a simple test:

public static void main(String[] args) {
   String m = "a";
   m += "bc";
   String s1 = "mabc".substring(1);
   String s2 = "abc";

   System.out.println(m == "abc");
   System.out.println(m == s1);
   System.out.println(m == s2);
   System.out.println(s1 == s2);
}

Shouldn't the result be "true, true, true, true", if m, s1, s2 point to the same object ("abc")? Instead the result is "false, false, false, false"!

Robert
  • 81
  • 3

2 Answers2

6

The result would be true in that case - but m, s1 and s2 all refer to different strings. Interning is performed automatically for constant string expressions, and can be explicitly invoked by calling the intern method, but it doesn't happen for string concatenation and substrings automatically.

In Sun's Java 7 implementation, x.substring(0) will actually return the same reference (x) back again, but I don't believe that's guaranteed by the API.

To look at your example:

public String makinStrings() {
   String m = "Fred47";
   String s = "Fred";
   s = s + "47";
   s = s.substring(0);
   return s.toString();
}

The first two lines require that there are two strings in memory, but I don't know exactly when it's guaranteed that the objects are created. Once they have been created, they will stick around - so calling makinStrings again won't create any more in those two lines.

The string concatenation will create a new string object.

The substring call won't create a new string object in the implementation I've looked at - but it could.

The call to s.toString() won't create a new string (and this is specified in the JavaDoc).

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
0

No, just because two strings are equal does not mean that their references are equal.

The compile interns some strings to save space, so if you try:

String s1 = "abc";
String s2 = "abc";

Then s1 == s2 will be true, but this is a special case and not a general rule. Strings generated at runtime in general do not share the same reference by default.

Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
  • I was expecting that the new String objects to be used from the String Pool if they exists. As java 5.0 the Numbers (Integer, Byte etc) are cached (at least the small numbers) and reused when parsed from Strings. I was expecting the same with Strings but it seems is not the case... – Robert Dec 14 '09 at 20:27
  • I suspect it's because the space/performance trade-off is not worth it for strings, whereas it is for Integer because of the large number of equal objects you might get when boxing. But you shouldn't rely on the current behaviour - it may change in future implementations. – Mark Byers Dec 14 '09 at 20:46
  • @Mark - correct ... interning a String is expensive, but looking to see if an Integer object already exists is cheap. – Stephen C Dec 15 '09 at 02:12