1、Java中數據存儲區域包括:java
1.寄存器:最快的存儲區,由編譯器根據需求進行分配,咱們在程序中沒法控制.
2. 棧:存放基本類型的變量數據和對象的引用,但對象自己不存放在棧中,而是存放在堆(new 出來的對象)或者常量池中(字符串常量對象存放在常量池中。)
3. 堆:存放全部new出來的對象。
4. 靜態域:存放靜態成員(static定義的)
5. 常量池:存放字符串常量和基本類型常量(public static final)。
6. 非RAM存儲:硬盤等永久存儲空間jvm
2、相關說明:優化
1.String類是不可變類,一個String對象所包含的字符串內容永遠不會被改變。spa
2."equals()"判斷兩個字符串對象的內容是否相同對象
3."=="判斷兩個String實例的引用是否相同blog
4. 當調用 intern()時,若是池已經包含一個等於此 String 對象的字符串(用 equals(Object) 方法肯定),則返回池中的字符串。不然,將此 String 對象添加到池中,並返回此 String 對象的引用。它遵循如下規則:對於任意兩個字符串 s 和 t,當且僅當 s.equals(t) 爲 true 時,s.intern() == t.intern() 才爲 true。 簡而言之,intern() 返回一個字符串,內容與調用它的字符串的內容相同,但必定取自具備惟一字符串的池。內存
5.字面量定義的字符串會自動調用intern()
例子:
String b = "abc"等價於
String b = "abc".intern()字符串
3、例子編譯器
例子A:
String str1 = "java";
String str2 = "java";
System.out.print(str1==str2);
返回值:true編譯
解說:
執行第一句:JVM首先在常量池中查找"java",以前常量池中沒有"java", 因此,jvm找不到"java"。所以,JVM會在常量池建立"java",而後在棧上建立str1,指向它;
執行第二句:由於執行第一句的時候,JVM已經在常量池中建立了"java", 所以JVM直接在棧上建立str2變量,指向"java"。
因此,它們的引用相同,即str1 == str2。
例子B:
String str1 = new String("java");
String str2 = new String("java");
System.out.print(str1==str2);
返回值:false
解說:
執行第一句:JVM在堆上建立一個"java"對象,在棧上建立str1變量,而後指向它;
執行第二句:在堆上再建立一個"java"對象,在棧上建立str2變量,指向它。
這兩個"java」對象雖然內容同樣,但內存地址不同,屬於不一樣的對象。所以,str1 != str2。
例子C:
String str1 = "java";
String str2 = "blog";
String s = str1+str2;
System.out.print(s=="javablog");
返回值:false
解說:
執行第一句:JVM會在常量池建立"java",而後在棧上建立str1,指向它;
執行第二句:JVM會在常量池建立"blog",而後在棧上建立str2,指向它;
執行第三句:JVM會在堆上建立一個對象,用於存儲str1+str2的結果,而後在棧上建立s變量指向這個對象。
執行第四句:JVM在常量池中建立"javablog",因此,s 和 "javablog"的內存地址不同。
所以 s != "javablog"。
例子D:
String str1 = "javablog";
String str2 = "java"+"blog";
System.out.println(str1 == str2);
返回值:true
解說:
String str2 = "java"+"blog"; //在編譯時被優化成String str2 = "javablog";
所以str1 == str2
例子E:
String s1 = "java";
String s2 = new String("java");
System.out.print(s1.intern()==s2.intern());
返回值:true
解說:
intern() 返回一個字符串,內容與調用它的字符串的內容相同,但必定取自具備惟一字符串的池。
例子F:
String str1 = "java";
String str2 = new String("java");
System.out.print(str1.equals(str2));
返回值:true
解說:
equals比較的是字符串內容