Java中String對象的存儲位置(學習筆記)


首先,String是final修飾的、immutable對象,它以一個個字符的方式存儲在字符數組中。
其次,String類型創建對象有兩種方式:①通過字面量賦值:會先去常量池中查找是否存在相同的字符串,若存在,棧中引用直接指定該字符串;若不存在,在常量池中進行緩存,再將棧中引用指向它。②通過new關鍵字:每次new出來的都是一個新的對象,在堆中開辟空間進行存儲。
又因為,在JDK1.7的HotSpot中,已經把原本放在永久代的字符串常量池移出,JDK8元空間徹底取代永久代,此時字符串常量池還在堆,所以String變量是以字符數組的形式儲在堆。
證明,str1和str2,指向的是同一個字符數組:

String str1="ab";
String str2=new String("ab");
Field field=str2.getClass().getDeclaredField("value");
field.setAccessible(true);
char[] sum=(char[]) field.get(str2);
sum[0]='w';
System.out.println(str1);//wb
System.out.println(str2);//wb

test直接演示String對象的創建位置:

package test.string.equal;

public class Main {
    
    /** 
     * 創建了三個對象,"helloworld對象創建在常量池中",每次new String()都會創建一個對象在堆內存中。
     */
    void test() {
     String s1="helloworld"; String s2
= new String("helloworld"); String s3= new String("helloworld"); } /** * 程序只創建一個字符串對象“Java”,存放在常量池中,所以s1==s2 為true */ void test1(){ String s1="Java"; String s2="Java"; System.out.println(s1==s2); } /** 第一個new String("Java"):創建了兩個對象,Java創建於常量池中,String對象創建於堆內存中。 * 第二個new String("Java"):由於常量池中有Java對象,所以只需創建一個對象,String對象創建於堆內存中。 * s1與s2分別指向String對象堆內存,所以s1==s2 為false */ void test2() { String s1=new String("Java"); String s2= new String("Java"); System.out.println(s1==s2); } /** 常量的值在編譯的時候就確定了,"hello"、"world"都是常量,因此s2的值在編譯的時候也確定了, * s2指向常量池中的"hello world",所以s1==s2為true * */ void test3() { String s1="hello world"; String s2="hello "+"world"; System.out.println(s1==s2); } /** s4由兩個String變量相加得到,不能再編譯時就確定下來,不能直接引用常量池中的"helloworld"對象,而是在堆內存中創建一個新的String對象並由s4指向 * 所以s1==s4為false * */ void test4() { String s1="helloworld"; String s2="hello"; String s3="world"; String s4=s2+s3; System.out.println(s1==s4); } /** s2與s3被final修飾為宏變量,不可更改,編譯器在程序使用該變量的地方直接使用該變量的值進行替代,所以s4的值在編譯的時候就為"helloworld" * 指向常量池中的"helloworld"對象 * 所以s1==s4為true * */ void test5() { String s1="helloworld"; final String s2="hello"; final String s3="world"; String s4=s2+s3; System.out.println(s1==s4); } public static void main(String[] args) { Main o = new Main(); o.test1(); o.test2(); o.test3(); o.test4(); o.test5(); } }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM