由String看Java堆棧問題,包括==以及equal()。
首先看代碼:
1
Java代碼 {
dp.sh.Toolbar.CopyToClipboard(this);return false;
}" href="http://writeblog.csdn.net/#">
- public class TestString {
- public static void main(String[] args) {
- String a0 = "abc";
- String b0 = "abc";
- if (a0 == b0) {
- System.out.print("==");
- } else {
- System.out.print("!=");
- }
- }
- }
public class TestString {public static void main(String[] args) {String a0 = "abc";String b0 = "abc";if (a0 == b0) {System.out.print("==");} else {System.out.print("!=");}}}
執行結果為:
==
2
Java代碼 {
dp.sh.Toolbar.CopyToClipboard(this);return false;
}" href="http://writeblog.csdn.net/#">
- public class TestString {
- public static void main(String[] args) {
- String a0 = String.valueOf("abc");
- String b0 = String.valueOf("abc");
- if (a0 == b0) {
- System.out.print("==");
- } else {
- System.out.print("!=");
- }
- }
- }
public class TestString {public static void main(String[] args) {String a0 = String.valueOf("abc");String b0 = String.valueOf("abc");if (a0 == b0) {System.out.print("==");} else {System.out.print("!=");}}}
執行結果為:
==
3
Java代碼 {
dp.sh.Toolbar.CopyToClipboard(this);return false;
}" href="http://writeblog.csdn.net/#">
- public class TestString {
- public static void main(String[] args) {
- String a0 = "abc"+"def";
- String b0 = "abcdef";
- if(a0==b0){
- System.out.print("==");
- }else{
- System.out.print("!=");
- }
- }
- }
public class TestString {public static void main(String[] args) {String a0 = "abc"+"def";String b0 = "abcdef";if(a0==b0){System.out.print("==");}else{System.out.print("!=");}}}
執行結果為:
==
4
Java代碼 {
dp.sh.Toolbar.CopyToClipboard(this);return false;
}" href="http://writeblog.csdn.net/#">
- public class TestString {
- public static void main(String[] args) {
- String a0 = "abc";
- String b0 = "def";
- String c0 = "abcdef";
- String d0 = a0 + b0;
- if (c0 == d0) {
- System.out.print("==");
- } else {
- System.out.print("!=");
- }
- }
- }
public class TestString {public static void main(String[] args) { String a0 = "abc";String b0 = "def";String c0 = "abcdef";String d0 = a0 + b0;if (c0 == d0) {System.out.print("==");} else {System.out.print("!=");}}}
執行結果為:
!=
5
Java代碼 {
dp.sh.Toolbar.CopyToClipboard(this);return false;
}" href="http://writeblog.csdn.net/#">
- public class TestString {
- public static void main(String[] args) {
- String a0 = new String("abc");
- String b0 = new String("abc");
- if (a0 == b0) {
- System.out.print("==");
- } else {
- System.out.print("!=");
- }
- }
- }
public class TestString {public static void main(String[] args) {String a0 = new String("abc");String b0 = new String("abc");if (a0 == b0) {System.out.print("==");} else {System.out.print("!=");}}}
執行結果為:
!=
6
Java代碼 {
dp.sh.Toolbar.CopyToClipboard(this);return false;
}" href="http://writeblog.csdn.net/#">
- public class TestString {
-
- public static void main(String[] args) {
-
- String a0 = String.valueOf("abc")+String.valueOf("def");
- String b0 = String.valueOf("abcdef");
-
- if (a0 == b0) {
- System.out.print("==");
- } else {
- System.out.print("!=");
- }
- }
-
- }
public class TestString {public static void main(String[] args) {String a0 = String.valueOf("abc")+String.valueOf("def");String b0 = String.valueOf("abcdef");if (a0 == b0) {System.out.print("==");} else {System.out.print("!=");}}}
執行結果為:
!=
我們的都知道,Java的記憶體配置策略:棧中存放基礎資料型別 (Elementary Data Type)(或者叫內建類型)以及參考型別(或者叫物件控點),而堆中存放對象資料。
String很特殊,根據Think In Java介紹:“通過編譯器和特殊的覆蓋或過載運算子+和+=,可將引號字串轉換成一個String”。可見引號字串本身並不是一個String,而是通過運算子的重載轉換成了String。注意:沒有=號。
故此:我們要問,引號字串通過重載以後轉換成String存在於什麼位置?
查詢網上沒有具體的分析,書籍上也沒有準確的說明。
根據執行結果猜想:
學習過類載入可能知道,有個常量區。
暫且假設將此部分資料存放於此空間中,看能否得到合理的解釋。
Java的記憶體配置棧中存放兩種類型資料:
1、基礎資料型別 (Elementary Data Type):此處疑問?存放的是具體的資料還是也是一個記憶體位址。
假設1:棧中存放的是具體的資料,當然所有出現在基本類型的操作均可以解釋。
假設2:資料存放於上邊提到的常量區,而棧中存放的是此常量區對應資料的地址。所有基礎資料型別 (Elementary Data Type)操作似乎也可以解釋。
其實Java設計師們很注重記憶體的利用,我們可能看見很多文章曾提到這樣一個概念,當int n =1;時,Java會在記憶體中搜尋,看有沒有1的存在,假如有的話,則不會重新分配空間建立1,如果沒有的話,則會建立1,假如int m=1;則Java不會再建立1的空間。可見似乎記憶體中存在一個存放資料的地方。如果用次觀點解釋假設2完全成立。
現在以下的結論均在假設2下展開。
2、參考型別:棧中存放的是對象的引用,此引用是通過new建立的對象在對中分配的地址。
現在分析String。
屬於什麼類型?基礎資料型別 (Elementary Data Type)、參考型別。
當作為String str = "abc";建立時,作為基本類型的假設2合理一些(參見第1部分代碼)。
當作為String str = new String("abc");建立時,毫無疑問作為參考型別處理(參見第5部分代碼)。
我們暫且將+作為一種Java特殊的處理機制,當它處理引號字串時不會採用new方式建立String(即像"abc"+"def"),而對於棧中資料處理時會採用new方式建立String(即像a+b)。(參見第3、4、6部分代碼)。
當作為String str = String.valueOf("abc");建立或者執行+時,完全可以解釋通過。
其實String.valueOf()可以看做是對"abc"的封裝,但不是new的(參見第2、6部分代碼)。
其實現在要是按照以上的觀點,可以得出這樣一種結論:
棧中存放的是控制代碼,包括基礎資料型別 (Elementary Data Type)。記憶體中存在另外一塊地區(常量區),存放基礎資料型別 (Elementary Data Type)資料以及引號字串資料。
堆中存放的是對象,且必須是new的或者通過+運算子的重載隱式new的。
亂想了一通,與一些理論違背,因為好多東西解釋不通,所以胡思亂想了。
歡迎評論,謝謝。