溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

String s = new String("xyz")創(chuàng)建了幾個(gè)對(duì)象

發(fā)布時(shí)間:2021-10-26 17:16:02 來(lái)源:億速云 閱讀:143 作者:iii 欄目:編程語(yǔ)言

本篇內(nèi)容主要講解“String s = new String("xyz")創(chuàng)建了幾個(gè)對(duì)象”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“String s = new String("xyz")創(chuàng)建了幾個(gè)對(duì)象”吧!

從方法區(qū)說(shuō)起

常量池存在于方法區(qū),而方法區(qū)在jdk1.7版本前后改變比較大,所以還是先來(lái)說(shuō)說(shuō)方法區(qū)的演變。

在jdk1.7版本之前,常量池存在于方法區(qū),方法區(qū)是堆的一個(gè)邏輯部分,他有一個(gè)名字叫做非堆。

String s = new String("xyz")創(chuàng)建了幾個(gè)對(duì)象

1.7版本把字符串常量池放到了堆中。

String s = new String("xyz")創(chuàng)建了幾個(gè)對(duì)象

而在1.8以后,則是移除了永久代,方法區(qū)概念保留,方法區(qū)的實(shí)現(xiàn)改為了元空間,常量池還是在堆中。

String s = new String("xyz")創(chuàng)建了幾個(gè)對(duì)象

為什么要說(shuō)方法區(qū)的改變,只是為了文章接下來(lái)的內(nèi)容不會(huì)由于JDK的版本而產(chǎn)生分歧,接下來(lái)內(nèi)容都會(huì)以jdk1.8版本作為基礎(chǔ)來(lái)討論。

String s = new String("xyz");

先來(lái)一段代碼

public class Test {      public static void main(String[] args) {          String s = "xyz";      }  }

接著我們javac編譯代碼,然后用javap來(lái)反編譯,執(zhí)行javap -c Test

String s = new String("xyz")創(chuàng)建了幾個(gè)對(duì)象

從結(jié)果來(lái)看,ldc命令在常量池中創(chuàng)建了一個(gè)"xyz"的對(duì)象,然后把他推至操作數(shù)棧頂,然后astore保存到局部變量,return返回。

接著看第二段面試題中的代碼

public class Test {      public static void main(String[] args) {          String s = new String("xyz");      }  }

同樣反編譯分析

String s = new String("xyz")創(chuàng)建了幾個(gè)對(duì)象

很明顯,我們看到new 創(chuàng)建了一個(gè)String對(duì)象,同時(shí)ldc在常量池中創(chuàng)建了"xyz"字符串對(duì)象,之后invokespecial執(zhí)行構(gòu)造函數(shù),astore_1賦值,return返回。

通過(guò)以上兩個(gè)例子,可以知道String s = new String("xyz"); 創(chuàng)建了2個(gè)對(duì)象,而有些答案說(shuō)的3個(gè)對(duì)象,則是把引用s也算作一個(gè)對(duì)象。

還有答案說(shuō)xyz存在就創(chuàng)建了2個(gè),不存在就創(chuàng)建了3個(gè)(包含引用s),再來(lái)測(cè)試一下。

public class Test {      public static void main(String[] args) {          String s = "xyz";          String s2 = new String("xyz");      }  }

String s = new String("xyz")創(chuàng)建了幾個(gè)對(duì)象

從這里,很明顯的發(fā)現(xiàn)這就是我們例子1和2的一個(gè)結(jié)合,但是注意兩次ldc后面的#2,#號(hào)代表著索引,說(shuō)明第二次new String("xyz")的時(shí)候并沒(méi)有重新創(chuàng)建xyz對(duì)象。

一些常見(jiàn)的指令助記符含義:

  1.  nop, 什么都不做。

  2.  aconst_null,將 null 推送至棧頂。

  3.  iconst_i(變量數(shù)字),將 int 型 i 推送至棧頂。同理有l(wèi)const_0,fconst_0這種你應(yīng)該知道什么意思了

  4.  ldc,將 int,float 或 String 型常量值從常量池中推送至棧頂。

  5.  iload,將指定的 int 型局部變量推送至棧頂。

  6.  istore,將棧頂 int 型數(shù)值存入指定局部變量。同理astore_i代表將棧頂引用型數(shù)值存入第i個(gè)局部變量。

  7.  dup,復(fù)制棧頂數(shù)值并將復(fù)制值壓入棧頂。

  8.  invokevirtual,調(diào)用實(shí)例方法。

  9.  invokespecial,調(diào)用超類(lèi)構(gòu)造方法,實(shí)例初始化方法,私有方法。

  10.  invokestatic,調(diào)用靜態(tài)方法。

  11.  invokeinterface,調(diào)用接口方法。

  12.  invokedynamic,調(diào)用動(dòng)態(tài)鏈接方法。

  13.  new,創(chuàng)建一個(gè)對(duì)象,并將其引用值壓入棧頂。

總結(jié)

到底創(chuàng)建了幾個(gè)對(duì)象呢?

  1.  如果xyz不存在,引用算對(duì)象的話,那就是3個(gè)

  2.  如果xyz不存在,引用不算對(duì)象的話,那就是2個(gè)

  3.  如果xyz存在,引用算對(duì)象的話,那就是2個(gè)

  4.  如果xyz存在,引用不算對(duì)象的話,那就是1個(gè)

到此,相信大家對(duì)“String s = new String("xyz")創(chuàng)建了幾個(gè)對(duì)象”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI