Java String面試題
試題一、String s = new String(“abc”)建立了幾個物件?
String s = new String(“abc”)實際上是”abc”本身就是字串池中的一個物件,在執行 new String()時,把字串池的字串”abc”複製到堆中,並把這個物件的應用交給s,所以建立了兩個String物件,一個在字串池中,一個在堆中。(注:我們假設的是字串池中預設是沒有abc字串的,如果之前已存在的話,則該題的答案就是一個物件了)
下面看這個程式,建立了幾個物件。
public class stringPool {
public static void main(String[] args) {
String s1 = new String("abc");
String s2 = new String("abc");
if (s1 == s2) {
System.out.println("在堆中只建立了一個物件");
} else {
System.out.println("在堆中建立了二個物件");
}
}
}
輸出:
在堆中建立了二個物件
可知在堆中建立了兩個物件,但是在字串池中還有一個物件,所以共建立了三個物件。
試題二、String name=new String(“Java”+”hello”);建立了幾個物件?
對於該題常見的解釋有如下兩種,
其一:
1.”java”建立了一個物件,存於String常量池
2.”hello”建立了一個物件,存於String常量池
3.”java”+”hello”,建立了一個物件,存於常量池(基於字串的+操作,如帶有引用的,將在堆中建立物件,否則值會存於字元常量池)
4.new將會建立一個物件,將字元常量池中的”javahello”複製到堆中
此例將建立4個物件
其二:
像”java”+”hello”,java在編譯期間會自己先優化的,會合併成一個物件”javahello”的,然後在字串池中保留,然後new的時候再在堆中建立新的物件。因此共建立了兩個物件。
[root@hina stringtest]# more TestString.java
public class TestString{
public static void main(String[] args) {
String name = new String("java" + "hello");
}
}
[root@hina stringtest]# javac TestString.java
[root@hina stringtest]# javap -c TestString
Compiled from "TestString.java"
public class TestString extends java.lang.Object{
public TestString();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #2; //class java/lang/String
3: dup
4: ldc #3; //String javahello
6: invokespecial #4; //Method java/lang/String."<init>":(Ljava/lang/String;)V
9: astore_1
10: return
}
看清楚了,編譯的位元組碼裡沒有java也沒有hello,而是javahello。這個javahello不是在執行的時候被建立,而是jvm啟動的時候初始化好的。
實際上只有一個new,也就是說只建立了一個物件:
0 new 建立string物件
3 dup 複製頂棧內容,這是所有new物件都會做的事情,因為jvm要做
4 ldc 把常量池中javahello的引用壓入棧中
6 invokespecial 物件初始化
9 astore_1 把棧中的引用賦給第一個變數
所以,上面的第二種解釋是正確的,即:建立了兩個物件,一個javahello的物件在字串池中,一個new出的物件在堆上。
試題三,見下面的程式碼
String str1="abc";
String str2="def";
String str3=str1+str2;
System.out.println(str3=="abcdef");
//結果是false
因為str3指向堆中的”abcdef”物件並未是字串池中的物件,而”abcdef”是字串池中的物件,所以結果為false。JVM對String str=”abc”物件放在常量池中是在編譯時做的,而String str3=str1+str2是在執行時刻才能知道的。new物件也是在執行時才做的。而這段程式碼總共建立了5個物件,字串池中兩個、堆中三個。+運算子會在堆中建立來兩個String物件,也就是說從字串池中複製這兩個值,然後在堆中建立兩個物件,然後再建立物件str3,然後將”abcdef”的堆地址賦給str3。
而如果,如下的程式碼:
String str="abc"+"def"; //直接將"abcdef"放入字串池中
System.out.println(str=="abcdef");
//結果為true
String str1="abc";
String str2=str1+"def"; //str1是在堆中建立的物件
System.out.println(str2=="abcdef");
//結果為false
本例子說明,str2也並未放到字串池中。從上面的結果中我們不難看出,只有使用引號包含文字的方式建立的String物件之間使用“+”連線產生的新物件才會被加入字串池中。對於所有包含new方式新建物件(包括null)的“+”連線表示式,它所產生的新物件都不會被加入字串池中。
由於字串物件的大量使用(它是一個物件,一般而言物件總是在堆中分配記憶體),Java中為了節省記憶體空間和執行時間(如比較字串時,==比equals()快),在編譯階段就把所有的字串文字放到一個字串池中,而執行時字串池成為常量池的一部分。字串池的好處,就是該池中所有相同的字串常量被合併,只佔用一個空間。
我們知道,對兩個引用變數,使用==判斷它們的值(引用)是否相等,即指向同一個物件:
String s1 = "abc" ;
String s2 = "abc" ;
if( s1 == s2 )
System.out.println("s1,s2 refer to the same object");
else
System.out.println("trouble");
這裡的輸出顯示,兩個字串文字儲存為一個物件。就是說,上面的程式碼只在字串中建立了一個String物件。
現在看String s = new String(“abc”);語句,這裡”abc”本身就是pool中的一個物件,而在執行時執行new String()時,將字串池中的物件複製一份放到堆中,並且把堆中的這個物件的引用交給s持有。ok,這條語句就建立了2個String物件。
String s1 = new String("abc") ;
String s2 = new String("abc") ;
if( s1 == s2 ){ //不會執行的語句}
這時用==判斷就可知,雖然兩個物件的”內容”相同(equals()判斷),但兩個引用變數所持有的引用不同,上面的程式碼建立了幾個String 物件? (3個,字串池中1個,堆中2個。)
建立字串有兩種方式:兩種記憶體區域(字串池,堆)
1.” ” 引號建立的字串在字串池中
2.new,new建立字串時首先檢視池中是否有相同值的字串,如果有,則拷貝一份到堆中,然後返回堆中的地址;如果池中沒有,則在堆中建立一份,然後返回堆中的地址(注意,此時不需要從堆中複製到池中,否則導致浪費池的空間)
3.另外,對字串進行賦值時,如果右運算元含有一個或一個以上的字串引用時,則在堆中再建立一個字串物件,返回引用;如String str2=str1+ “abc”;
比較兩個已經存在於字串池中字串物件可以用”==”進行,擁有比equals操作符更快的速度。
相關文章
- JAVA面試題 String s = new String("xyz");產生了幾個物件?Java面試題物件
- Java面試鍊金系列 (1) | 關於String類的常見面試題剖析Java面試題
- 面試之Java String 編碼相關面試Java
- java String類練習題Java
- java面試題Java面試題
- 【Java面試】Java常見IO面試題!Java面試題
- 【Java面試】Java設計模式面試題!Java設計模式面試題
- JAVA面試題 java部分Java面試題
- 5道面試題,拿捏String底層原理!面試題
- 100道JAVA面試題+JAVA面試題參考答案Java面試題
- 【Java面試題】Java面試之多執行緒!Java面試題執行緒
- Java SSM面試題JavaSSM面試題
- Java面試題解析Java面試題
- JAVA面試題(8)Java面試題
- java 面試題1Java面試題
- Java面試題(一)Java面試題
- Java 面試題集Java面試題
- java面試問題Java面試
- Java面試題全集Java面試題
- 阿里java面試題阿里Java面試題
- Java集合---面試題Java面試題
- Java面試題收集Java面試題
- Java面試試題Java面試
- java面試題大全Java面試題
- 面試題-JAVA反射面試題Java反射
- 面試題-JAVA IO面試題Java
- JAVA面試題-CORE JAVA部分Java面試題
- 【Java面試】 Javascript常見面試題!JavaScript面試題
- 【Java面試】Servlet常見面試題!JavaServlet面試題
- 【Java面試】new String("abc")到底建立了幾個物件?Java面試物件
- java經典面試題Java面試題
- Java大廠面試題Java面試題
- Java面試題整理《上》Java面試題
- Java Collection集合面試題Java面試題
- 中高階Java面試題Java面試題
- Java面試題全集(下)Java面試題
- Java併發面試題Java面試題
- JAVA最新面試題分享Java面試題