3

Suppose we have program like this:

import java.io.*;

public class ReadString {

   public static void main (String[] args) {

      //  prompt the user to enter their name
      System.out.print("Enter your name: ");

      //  open up standard input
      BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

      String userName = null;
      String userNameCopy = null;

      //  read the username from the command-line; need to use try/catch with the
      //  readLine() method
      try {
         userName = br.readLine();
         System.out.print("Enter your name once again: ");
         userNameCopy = br.readLine();
      } catch (IOException ioe) {
         System.out.println("IO error trying to read your name!");
         System.exit(1);
      }

      System.out.println("Thanks for the name, " + userName);

   }

}  // end of ReadString class

Now, if user types his username twice, userName and userNameCopy Strings will have the same value. Since strings are immutable, will Java compiler be smart enough to use only one memory object with the two references to it, or is this behavior reserved only for the string literals hard-coded into the program?

If the answer is "No, compiler will create two separate object on the heap". why is that so? Is it because searching for the exact match from the pool is slow? If it is, couldn't string pool be implemented like some sort of hash table, or something similar?

Nemanja Boric
  • 21,627
  • 6
  • 67
  • 91
  • 2
    Thou shalt not assume anything about String identity – John Dvorak Apr 01 '13 at 17:43
  • Thou shalt only assume those things about String identity that are specified in the JLS and/or the String API documentation. – Patricia Shanahan Apr 01 '13 at 17:44
  • 1
    @PatriciaShanahan not even those are worth assuming IMO – John Dvorak Apr 01 '13 at 17:45
  • No, I will not, I guess I should never rely on reference compassion when checking the strings for the equality. I am just asking this not for the "real coding", but as something interesting that I may learn. – Nemanja Boric Apr 01 '13 at 17:45
  • "If it is, couldn't string pool be implemented like some sort of hash table, or something similar?" Hash tables are typically still slower than just generating fresh `String` objects. Allocation is _really fast and really cheap._ – Louis Wasserman Apr 01 '13 at 17:50
  • @LouisWasserman unless you're fighting for memory – John Dvorak Apr 01 '13 at 17:51

3 Answers3

6

The pool is implemented as a hashed data structure. Java leaves the decision about whether to do the search, and share non-literal String objects, up to the programmer. See the String method intern().

Patricia Shanahan
  • 25,849
  • 4
  • 38
  • 75
  • Great tip on the 'String.intern()' method! I've searched a little bit for it, and I've found good reference in the accepted answer in this question: http://stackoverflow.com/questions/1855170/when-should-we-use-intern-method-of-string – Nemanja Boric Apr 01 '13 at 17:49
3

It's pretty irrelevant as to where you are reading the strings from. Fact of the matter is that your input stream implementation creates new strings from the byte data that is read from the source. But, you can only know this for sure by looking at the source code of the implementation class. In general, you should not assume strings are being interned by a class unless it explicitly states so in its documentation.

Perception
  • 79,279
  • 19
  • 185
  • 195
1

String Pool implementation is decided at compile time by the compiler.StringPool is implemented by HashMap . Now in your case since compiler is not sure of what String you will input to those variables so now it is responsibility of runtime to create the String object on heap. It is just the way Java can handle the Strings. And still if you want to put the String in StringPool you can use String#intern()

Vishal K
  • 12,976
  • 2
  • 27
  • 38