String intern puzzle

A String based puzzle for you.

The following program

String te = "te", st = "st";
// "test".length();
String username = te + st;
username.intern();
System.out.println("String object the same is: " 

    + (username == "test"));

prints under Java 7 update 7.

String object the same is: true

but uncomment the "test".length(); line, or run with Java 6 and it prints

String object the same is: false

Can you work out why?

Comments

  1. because te + st is computed in runtime unlike "te" + "st" which works on literals?

    in other words te + st is more like new String("test") which creates new object even if "test" already exists in the pool

    is that right?

    ReplyDelete
  2. String literals are interned automatically.

    Also the JavaDoc for String#intern() mentions:

    "When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned."

    Thus, username.intern() will return the "test" string from the pool but will not change the object reference of username and in the end username and "test" do not refer to the same String object (from the pool).

    ReplyDelete
  3. with commented "test".length() line:

    String object the same is: false

    jdk 1.6.0.24

    ReplyDelete
  4. case 1:
    the string "test" is not present in pool use, so the object username is added to pool. thus username=="test" becomes true

    case 2:
    the line "test".length() adds this string to pool. and the method call username.intern() return reference to the string in pool.
    so username=="test" returns false

    ReplyDelete
  5. I should have noted that this only happens under Java 7. Java 6 behaves differently.

    ReplyDelete
  6. Related links

    http://stackoverflow.com/questions/12278323/string-intern-puzzles

    http://stackoverflow.com/questions/7065337/intern-behaving-differently-in-java-6-and-java-7

    ReplyDelete
  7. I guess using == is commonly understood as the wrong way in Java to test string equality

    We are observing coincidences that happens in different situations in the constant pool, any future implementation may or may not surface such behaviour
    with no weight on compliance whatsoever

    this is very much like the insertion order of keys in a hash

    ReplyDelete
  8. Looks like java6 puts a copy to the pool, but java7 puts the object itself.

    ReplyDelete
  9. @ILLya Could you could talk about the changes in the JDK which explain the puzzle?

    ReplyDelete
    Replies
    1. http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6962931

      Huhh. I missed this change...

      Delete

Post a Comment

Popular posts from this blog

Java is Very Fast, If You Don’t Create Many Objects

System wide unique nanosecond timestamps

Comparing Approaches to Durability in Low Latency Messaging Queues