2013-04-01 22 views
3

假設我們有這樣的程序:現在將從System.in中讀取的兩個相同的字符串存儲在公共內存位置中嗎?

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編譯器是否足夠聰明,只能使用一個帶有兩個引用的內存對象,還是隻保留硬編碼到程序中的字符串文字?

如果答案是「否,編譯器將在堆上創建兩個單獨的對象」。爲什麼?是否因爲搜索池中的精確匹配很慢?如果是這樣,不能像某種哈希表或類似的東西實現字符串池?

+2

不應該假定任何關於字符串標識的東西 –

+0

只應該假設那些在JLS和/或String API文檔中指定的關於字符串標識的東西。 –

+1

@PatriciaShanahan甚至沒有那些值得假設的IMO –

回答

6

池被實現爲散列數據結構。 Java決定是否執行搜索,並將非字面的String對象分享給程序員。請參閱字符串方法intern()

+0

關於'String.intern()'方法的大提示!我已經搜索了一點點,並且在這個問題的接受答案中找到了很好的參考:http://stackoverflow.com/questions/1855170/when-should-we-use-intern-method-of -串 –

3

這對你從哪裏讀字符串來說是非常不相干的。問題的實質是,您的輸入流實現將從從源讀取的字節數據中創建新的字符串。但是,您只能通過查看實現類的源代碼來了解這一點。一般來說,除非在文檔中明確聲明,否則不應該假設字符串正在被類實現。

1

字符串池的實現是由compiler.StringPool在編譯時由HashMap實現的。現在在你的情況下,因爲編譯器不確定你將輸入到這些變量的字符串,所以現在在堆中創建String對象是運行時的責任。這正是Java可以處理字符串的方式。如果你想把字符串放在StringPool中,你可以使用String#intern()

相關問題