String sb = new String("sb");到底創建了幾個實例?

String sb = new String(“sb”);到底創建了幾個實例?

很多人都在討論這個問題,當然這個問題是沒有什麼意義的。但是如果可以學到新的知識,那討論便有了意義。

之前博主不知道如何查看字節碼,最近看了一些文章。本文將從字節碼的角度分析這個問題。

對於這個問題,不考慮特殊情況是2個。
1.一個是字符串字面量”sb”所對應的、駐留(intern)在一個全局共享的字符串常量池中的實例。
2.通過new String(String)創建並初始化的、內容與”sb”相同的實例。

下面我們通過例子來感知下。
很簡單的例子。

這裏寫圖片描述

通過:

javac identity.java.

然後:

對生成的identity.class字節碼文件進行反彙編。
javap指令。

javap -c identity.class

結果如下圖:
這裏寫圖片描述

這就是字節碼執行的步驟。

先看下java指令的意思。
1.new 創建一個對象,並將其引用值壓入棧頂
2.dup 複製棧頂數值並將複製值壓入棧頂
3.ldc 將int, float或String型常量值從常量池中推送至棧頂
4.invokespecial 調用超類構造方法,實例初始化方法,私有方法(初始化)
5.putfield 爲指定的類的實例域賦值

而對於我們重要的就是
new和ldc指令。new執行了一次,創建了String對象。ldc執行了一次,從常量池中推送至棧頂。

很明顯,有兩個。

通過字節碼的解釋到此結束。

鏈接

java指令表格

當然關於此類的討論是沒什麼太多意義的,當然對於這個問題的問法,也會有不同的答案。

比如:在運行時,有幾個實例。
那麼這個答案就不一定了。因爲不同的jvm虛擬機在編譯時會做優化,所以到運行時,爲了更好的運行,有些早已給gc掉了。這在不同的jvm虛擬機上可能結果是不同的。

附上大神的解釋

關於問題的解釋

Ending.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章