為什么會輸出上邊的結果呢,String x = "Hello" 的方式,Java 虛擬機會將其分配到常量池中,而常量池中沒有重復的元素,比如當執行“Hello”時,java虛擬機會先在常量池中檢索是否已經有“Hello”,如果有那么就將“代理”的地址賦給變量,如果沒有就創建一個,然后在賦給變量;而 String z = new String(“Hello”) 則會被分到堆內存中,即使內容一樣還是會創建新的對象。
?
上面程序中的"==“是判斷兩個對象引用的地址是否相同,也就是判斷是否為同一個對象,a1與a2 返回為true,a1與a3返回則是false。說明a1與a2引用的同一個對象的地址,a3則與其它兩個引用不是同一個對象地址。
Java為了避免產生大量的String對象,設計了一個字符串常量池。工作原理是這樣的,創建一個字符串時,JVM首先為檢查字符串常量池中是否有值相等的字符串,如果有,則不再創建,直接返回該字符串的引用地址,若沒有,則創建,然后放到字符串常量池中,并返回新創建的字符串的引用地址。所以上面a1與a2引用地址相同。
那為什么a3與a1、a2引用的不是同一個字符串地址呢? String a3=new String(“代理Hello); JVM首先是在字符串常量池中找"Hello” 字符串,如果沒有創建字符串常量,然后放到常量池中,若已存在,則不需要創建;當遇到 new 時,還會在內存(不是字符串常量池中,而是在堆里面)上創建一個新的String對象,存儲"Hello",并將內存上的String對象引用地址返回,所以a3與a1、a2引用的不是同一個字符串地址。內存結構圖如下: