字符串內容相同而地址值不同,創建字符串內存地址的引用


1.String類(特殊的類)java.lang.String
表示字符串,本質是一個char[]數組

//public String(String original) 構造方法 public String(String original) { this.value = original.value; this.hash = original.hash; } private final char value[];

從構造方法源碼可以看出String類型的對象調用的是一個char[]數組,
由private final修飾,被final修飾就不能做出更改。這也是字符串不可改變的原因

2.實例化String對象 可以直接進行賦值操作
方式一:String s1=new String(“hello”);利用String類中的構造方法
方式二: String s2=“hello”;

 public static void main(String[] args) { String s1=new String("hello"); String s2="hello"; System.out.println("s1:"+s1); System.out.println("s2:"+s2); System.out.println(s1==s2);//false內容相同但地址值不同 //運行結果 s1:hello s2:hello false

廢話不多說,直接上圖。
在這里插入圖片描述
3.字符串是常量,會保存在常量池。
注意:必須使用雙引號包裹的字符串才是常量,會保存到常量池。
s1和s2的地址值()是不相同的,因為存儲機制是不一樣的
但我們直接使用雙引號(" ")寫出一個字符串時,會先在常量池查找這個字符串
如果沒有相同的則會在常量池開辟空間並創建字符串,如果有則會直接使用常量池中的字符串
4.內存存儲的分配:
s1創建的對象為字符串,所以會先在元空間(Metaspace)中的常量池保存字符“hello”,而因為new 需要創建對象,所以會在堆內存中開辟空間(堆內存開辟的空間會在堆中有一個新的內存地址)並保存元空間中的“hello”內存地址值(引用)堆內存中的地址會傳給棧中main()里的String s1,而s2會在常量池創建,
因為“hello”在元空間存在,所以s2僅僅保存的是元空間中常量池的hello內存引用,不會指向堆內存。
所以:
s1的內存地址引用 :
創建時:常量池 ->堆->s1(棧)
調用時:s1(棧)->堆->常量池
s2的內存指向為:
創建時:常量池->s2(棧)
調用時:s2(棧)->常量池
5.需要注意的是不同的jdk版本常量池的位置也會不同,本文以JDK8為例。
在JDK6以及之前,常量池在方法區
在JDK7的時候,常量池在堆內存
在JDK8的時候,常量池在元空間(方法區)

如有錯誤,請指出,我會及時更正。
三人行必有我師焉,謝謝。


免責聲明!

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



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