String深入
目錄
new String()
String.intern()
字符串常量賦值
常量字符串的“+”操作
常量字符串和變量拼接時
JDK1.7之后intern()
示例
new String()
new String()是在堆上創建一個對象,對象屬于堆。
String.intern()
String.intern(),是把字符串移到常量池,并把常量池中引用返回。
字符串常量賦值
先在常量池中查找,找到直接返回地址,沒有則添加到常量池,再返回地址。
常量字符串的“+”操作
編譯階段直接會合成為一個字符串。如string str=”JA”+”VA”,在編譯階段會直接合并成語句String str=”JAVA”,于是會去常量池中查找是否存在”JAVA”,從而進行創建或引用。?
常量字符串和變量拼接時
(如:String str3=baseStr + “01”;)會調用stringBuilder.append()在堆上創建新的對象
JDK1.7之后intern()
tern方法還是會先去查詢常量池中是否有已經存在,如果存在,則返回常量池中的引用,這一點與之前沒有區別,區別在于,如果在常量池找不到對應的字符串,則不會再將字符串拷貝到常量池,而只是在常量池中生成一個對原字符串的引用。簡單的說,就是往常量池放的東西變了:原來在常量池中找不到時,復制一個副本放到常量池,1.7后則是將在堆上的地址引用復制到常量池
---------------------
作者:唐大麥
來源:CSDN
原文:https://blog.csdn.net/soonfly/article/details/70147205
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!
示例
String s1 = new String("aaa"); String s2 = "aaa"; System.out.println(s1 == s2); // false。s1指向堆中對象地址。s2指向常量池中地址。s1 = new String("bbb").intern(); //指向常量池地址 s2 = "bbb"; //指向常量池地址 System.out.println(s1 == s2); // trues1 = "ccc"; s2 = "ccc"; System.out.println(s1 == s2); // true 。都指向常量池地址s1 = new String("ddd").intern(); s2 = new String("ddd").intern(); System.out.println(s1 == s2); // true 。都指向常量池地址s1 = "ab" + "cd"; //字符串字面量連接 s2 = "abcd"; System.out.println(s1 == s2); // true 。都指向常量池地址String temp = "hh"; s1 = "a" + temp; //堆中地址。 // 如果調用s1.intern 則最終返回true s2 = "ahh"; System.out.println(s1 == s2); // falsetemp = "hh".intern(); //常量池地址 s1 = "a" + temp; //堆中地址 s2 = "ahh"; //常量池地址 System.out.println(s1 == s2); // falsetemp = "hh".intern(); s1 = ("a" + temp).intern(); //常量池地址 s2 = "ahh"; //常量池地址 System.out.println(s1 == s2); // trues1 = new String("1"); // 同時會生成堆中的對象 以及常量池中1的對象,但是此時s1是指向堆中的對象的 s1.intern(); // 常量池中的已經存在 s2 = "1"; System.out.println(s1 == s2); // falseString s3 = new String("1") + new String("1"); // 此時生成了四個對象 常量池中的"1" + 2個堆中的"1" + s3指向的堆中的對象(注此時常量池不會生成"11") s3.intern(); // jdk1.7之后,常量池不僅僅可以存儲對象,還可以存儲對象的引用,會直接將s3的地址存儲在常量池 String s4 = "11"; // jdk1.7之后,常量池中的地址其實就是s3的地址 System.out.println(s3 == s4); // jdk1.7之前false, jdk1.7之后trues3 = new String("2") + new String("2"); s4 = "22"; // 常量池中不存在22,所以會新開辟一個存儲22對象的常量池地址 s3.intern(); // 常量池22的地址和s3的地址不同 System.out.println(s3 == s4); // false// 對于什么時候會在常量池存儲字符串對象,我想我們可以基本得出結論: 1. 顯示調用String的intern方法的時候; 2. 直接聲明字符串字面常量的時候,例如: String a = "aaa"; // 3. 字符串直接常量相加的時候,例如: String c = "aa" + "bb"; 其中的aa/bb只要有任何一個不是字符串字面常量形式,都不會在常量池生成"aabb". 且此時jvm做了優化,不// 會同時生成"aa"和"bb"在字符串常量池中?
總結
- 上一篇: Mysql DDL
- 下一篇: Eclipse Debug maven