面試題之String str = new String("abc"); 創建了幾個對象


今天去面試的時候碰到了這個問題:String str = new String("abc"); 創建了幾個對象,回來自己研究並查閱資料才發現答錯了。。
網上的爭論不少,有的說是兩個,答案應該是:兩個或一個
理由解釋如下:
都了解java 的字符串常量緩沖區(字符串池,字符串常量池),
如果代碼是這樣的:

 

 

[java]  view plain  copy
 
  1. String str2 = new String("abc");  


並且 abc 字符串之前沒有用過,這毫無疑問創建了兩個對象,一個是new  String 創建的一個新的對象,一個是常量“abc”對象的內容創建出的一個新的String對象,

 

 

但是如果代碼是這樣子的:

 

[java]  view plain  copy
 
  1. String str1 = "abc";  
  2.   
  3. String str2 = new String("abc");  


嗯,創建幾個就不好說了,我們還是測試一下吧,首先我們打開cmd.exe, 通過javac *.java編譯好該Java文件,然后通過命令javap -c *來查看java編譯后的ByteCode字節碼,

 

ldc的含義是:將常量值從常量池中取出來並且壓入棧中。從上圖中,我們可以看到第0行和第7行中的字符串引用是同一個,這說明了,在編譯期間,該字符串變量的值已經確定了下來,並且將該字符串值緩存在緩沖區中,同時讓該變量指向該字符串值,后面如果有使用相同的字符串值,則繼續指向同一個字符串值

所以String str2 = new String("abc"); 此時就創建一個對象,而abc 則是從字符串常量緩沖區中取出來的。

ok。就是這個樣子。

 

 

 

 

 String str = new String("abc"); 首先要看常量池里是否有“abc”這個字符串,如果有,則創建一個,如果沒有,則創建兩個。
我們可以把上面這行代碼分成String str、=、"abc"和new String()四部分來看待。String str只是定義了一個名為str的String類型的變量,因此它並沒有創建對象;=是對變量str進行初始化,將某個對象的引用(或者叫句柄)賦值給它,顯然也沒有創建對象;現在只剩下new String("abc")了。那么,new String("abc")為什么又能被看成"abc"和new String()呢?
我們來看一下被我們調用了的String的構造器: 
public String(String original) { //other code ... } 大家都知道,我們常用的創建一個類的實例(對象)的方法有以下兩種:
一,使用new創建對象。 
二、調用Class類的newInstance方法,利用反射機制創建對象。
我們正是使用new調用了String類的上面那個構造器方法創建了一個對象,並將它的引用賦值給了str變量。同時我們注意到,被調用的構造器方法接受的參數也是一個String對象,這個對象正是"abc"。由此我們又要引入另外一種創建String對象的方式的討論——引號內包含文本。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM