JAVA进阶开发之(String字符串的存储原理)
我們現在開始學習的就是一些工具類
這些工具類只需要我們學會查閱幫助文檔進行開發就可以實現很多功能
?
?
例如:我們查看工具類String
?
關于java JDK中內置的一個類:java.lang.String
1、String表示字符串類型,屬于引用數據類型,不屬于基本數據類型
2、在java中隨便用“雙引號”括起來的都是String對象。
例如:"abc"? "Hello World" ,這兩個是String對象
3、java中規定,雙引號括起來的字符串,是不可變的,也就是說"abc"從出生到死亡,不可能變成"abcd"
4、在JDK中,雙引號括起來的字符串
例如:"abc" "Hello World",都是直接存儲在"方法區" 的 "字符串常量池" 中(JDK8中字符串常量池在堆中)
5、JAVA的lang包路徑下的東西不需要導包也可以用,這是SUN公司給lang包的權限
?
?
提問 :為什么SUN公司把字符串存儲在一個"字符串常量池"中呢?
原因:字符串在實際的開發中使用太頻繁,目的是為了提高效率
?
以下是JVM示圖:
第一步:方法區中首先進行類加載,類加載進入到方法區中
第二步:程序執行,main主方法會執行,棧區會壓入一個main方法棧幀,在棧幀中,引用類型String s1變量中存儲的不是引號的內容,其實是引號的內容的內存地址,引號的內容就是字符串,這些字符串常量存儲在方法區中的字符串常量池(JDK8中字符串常量池在堆中)
第三步:在main方法棧幀中,引用類型String s2變量中存儲的也是內存地址,此時在字符串常量池中,"abcdef"直接從字符串常量池中提取,"xy"從字符串常量池中新建,"abcdefxy"也從字符串常量池中拼接新建,最終被s2存儲的內存地址指向"abcdefxy"
代碼演示:
public class StringTest01 {public static void main(String[] args) {String s1="abcdef";String s2="abcdef"+"xy";} }?
以下是代碼演示:
public class StringTest01 {public static void main(String[] args) {//下面這兩行代碼表示底層創建了3個字符串對象,都在字符串常量池中String s1="abcdef";String s2="abcdef"+"xy";//下面演示的是調用String的構造方法//new一個對象就是調用構造方法//分析這個代碼中的"xy"是從哪里來的?//凡是雙引號括起來的都在字符串常量池中有一份//new一個對象的時候一定在堆內存中開辟空間String s3=new String("xy");} }?
以下是用new對象時對字符串常量池引用(間接引用)的不同?
?
?
?
下面再舉一個例子:
代碼如下:
驗證:s1和s2的內存地址是否相同
public class StringTest02 {public static void main(String[] args) {String s1="hello";String s2="hello";System.out.println(s1==s2);} }JVM示意圖:
?
原因:
"hello" 是存儲 在方法區的字符串常量池中 ,所以"hello"不會新建
== 比較的是變量中保存的內存地址
?
?
?
下面再舉一個例子:
public class StringTest02 {public static void main(String[] args) {String s1="hello";String s2="hello";System.out.println(s1==s2);String x=new String("xyz");String y=new String("xyz");System.out.println(x==y);} }?
?
JVM示意圖:
?
原因:
如上
?
結論:
字符創對象之間比較不能使用==
== 不夠保險,應該調用String類的equals方法
?
發現:Object類中并沒有重寫equals方法,于是乎我們找到String類中equals,發現SUN公司已經對它進行重寫了
?
?
接下來我們對其重寫進行測試:
public class StringTest02 {public static void main(String[] args) {String s1="hello";String s2="hello";System.out.println(s1==s2);String x=new String("xyz");String y=new String("xyz");System.out.println(x==y);System.out.println(x.equals(y));String k=new String("testString");System.out.println("testString".equals(k));System.out.println(k.equals("testString"));} }?
為什么:"testString" 這個字符串后面可以加? "? . " 呢?
因為:"testString"是一個String字符串對象,只要是對象都能調用方法
?
這兩句有什么區別呢:
System.out.println("testString".equals(k));System.out.println(k.equals("testString"));建議使用第一種方式,可以避免空指針異常(當一個對象不存在時又調用其方法會產生異常,例如變量k就可能是空指針)
?
?
?
?
?
總結
以上是生活随笔為你收集整理的JAVA进阶开发之(String字符串的存储原理)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux的实际操作:文件目录类的实用指
- 下一篇: Linux的实际操作:文件目录类的实用指