从System.in读取的两个相同的字符串是否会存储在公共内存位置?

时间:2013-04-01 17:41:06

标签: java

假设我们有这样的程序:

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

现在,如果用户输入两次用户名,userNameuserNameCopy字符串将具有相同的值。由于字符串是不可变的,Java编译器是否足够聪明,只能使用一个具有两个引用的内存对象,或者这种行为仅保留为硬编码到程序中的字符串文字?

如果答案是“否,编译器将在堆上创建两个单独的对象”。为什么会这样?是因为从游泳池搜索完全匹配是慢的吗?如果是,那么字符串池是不是可以像某种哈希表那样实现,或类似的东西?

3 个答案:

答案 0 :(得分:6)

池实现为散列数据结构。 Java决定是否进行搜索,并共享非文字的String对象,直到程序员。请参阅字符串方法intern()

答案 1 :(得分:3)

关于从哪里读取字符串,这几乎无关紧要。事实是你的输入流实现从源读取的字节数据创建新的字符串。但是,您只能通过查看实现类的源代码来确定这一点。一般情况下,除非在文档中明确说明字符串,否则不应假设字符串正在被类实现。

答案 2 :(得分:1)

String Pool实现由编译器在编译时决定.StringPool由HashMap实现。现在在你的情况下,因为编译器不确定你将输入哪些String这些变量,所以现在运行时负责在堆上创建String对象。这就是Java可以处理字符串的方式。如果你想把String放在StringPool中,你可以使用String#intern()