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執行了一次,從常量池中推送至棧頂。
很明顯,有兩個。
通過字節碼的解釋到此結束。
鏈接
當然關於此類的討論是沒什麼太多意義的,當然對於這個問題的問法,也會有不同的答案。
比如:在運行時,有幾個實例。
那麼這個答案就不一定了。因爲不同的jvm虛擬機在編譯時會做優化,所以到運行時,爲了更好的運行,有些早已給gc掉了。這在不同的jvm虛擬機上可能結果是不同的。
附上大神的解釋
Ending.