亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

關(guān)于 String.intern() 的思考

siberiawolf / 922人閱讀

摘要:我看到一個(gè)上的問(wèn)題是關(guān)于的感覺(jué)比較有意思于是自己也去探索了一下有了一些自己的見(jiàn)解于是在此記錄下來(lái)我們首先來(lái)看一個(gè)例子編程編程這個(gè)例子會(huì)輸出什么呢有些讀者朋友可能沒(méi)有想到其實(shí)上面的例子在不同的版本中運(yùn)行會(huì)有不同的結(jié)果的那么接下來(lái)我們來(lái)試一下吧

我看到一個(gè) segmentfault 上的問(wèn)題, 是關(guān)于 String.intern() 的, 感覺(jué)比較有意思, 于是自己也去探索了一下, 有了一些自己的見(jiàn)解, 于是在此記錄下來(lái).

我們首先來(lái)看一個(gè)例子:

// 1
String str1 = new StringBuilder("ja").append("va").toString();
System.out.println(str1.intern() == str1);

// 2
String str2 = new StringBuffer("編").append("程").toString();
System.out.println(str2.intern() == str2);

// 3
String str3 = new StringBuffer("編").append("程").toString();
System.out.println(str3.intern() == str3);

這個(gè)例子會(huì)輸出什么呢? 有些讀者朋友可能沒(méi)有想到, 其實(shí)上面的例子在不同的 JDK 版本中運(yùn)行, 會(huì)有不同的結(jié)果的. 那么接下來(lái)我們來(lái)試一下吧:

// 使用 JDK6 進(jìn)行編譯運(yùn)行:
false, false, false
// 使用 JDK7 進(jìn)行編譯運(yùn)行:
false, true, false

為什么結(jié)果會(huì)不同呢?
首先我們來(lái)看一下第一部分:

String str1 = new StringBuilder("ja").append("va").toString();
System.out.println(str1.intern() == str1);

這里 JDK6 和 JDK7 都是打印的 false, 其原因是 "java" 字符串常量比較特殊, 它是固定存在字符串常量池中的, 因此 "str1.intern()" 返回的就是字符串常量池中的對(duì)象的引用, 和堆上的 str1 就自然是不相等了.

接下來(lái)我們來(lái)分析一下第二部分的代碼:

// 2
String str2 = new StringBuffer("編").append("程").toString();
System.out.println(str2.intern() == str2);

在這里 JDK6 和 JDK7 的輸出有了差異, 其具體原因是 JDK6 和 JDK7 對(duì) String.intern() 方法的實(shí)現(xiàn)的不同.
在 JDK6 及以前的 JDK 中:

intern() 方法會(huì)把首次遇到的字符串實(shí)例 **復(fù)制** 到永久代中, 然后返回永久代中的實(shí)例.

而對(duì)于 JDK7 以及之上的JDK:

當(dāng)遇到第一次出現(xiàn)的字符串時(shí), intern() **不再?gòu)?fù)制實(shí)例**, 而是在常量池中記錄首次出現(xiàn)的實(shí)例的引用, 并且 intern() 返回的是此實(shí)例引用.

根據(jù) JDK6 和 JDK7 的 intern() 方法的區(qū)別, 我們就知道了在第二部分的代碼中, "編程" 這個(gè)字符串是第一次出現(xiàn)的, 因此在 JDK6 中, 會(huì)將此對(duì)象的實(shí)例拷貝一份然后存放到常量池中, intern() 返回的是在常量池中拷貝后的新對(duì)象的引用, 進(jìn)而就和堆上的 str1 不等了; 而在 JDK7 中, 由于 intern() 方法的實(shí)現(xiàn)不同, 這個(gè)方法并不會(huì)拷貝一份對(duì)象實(shí)例到常量池中, 而是在常量池中記錄此對(duì)象的引用, 因此 intern() 返回的引用其實(shí)和堆中的 str1 是一樣的.

有了前面的認(rèn)知, 我們對(duì)第三部分的代碼的輸出結(jié)果就比較熟悉了:

// 3
String str3 = new StringBuffer("編").append("程").toString();
System.out.println(str3.intern() == str3);

第三部分代碼和第二部分代碼其實(shí)是一樣的, "編程" 這個(gè)字符串已經(jīng)在第二部分的代碼中出現(xiàn)了, 因此在常量池中已經(jīng)存在了, 因此 str3.intern() 返回的是常量池中的對(duì)象的引用, 和堆上的 str3 自然是不一樣的, 因此不論在 JDK6 還是 JDK7 中, 輸出的都是 false.

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/66087.html

相關(guān)文章

  • 關(guān)于String.intern()和new StringBuilder("").

    摘要:對(duì)比較返回是因?yàn)檫@個(gè)字符串在執(zhí)之前已經(jīng)出現(xiàn)過(guò),字符串常量池中已經(jīng)有它的引用了,不符合首次出現(xiàn)的原則,而計(jì)算機(jī)軟件這個(gè)字符串則是首次出現(xiàn)的,因此返回。 在《深入理解Java虛擬機(jī)》書中,提到在jdk1.7的版本中用String.intern()返回引用。 public class RuntimeConstantPoolOOM { public static void main(S...

    derek_334892 評(píng)論0 收藏0
  • join()方法神奇用處與Intern機(jī)制軟肋

    摘要:機(jī)制失效的情況方法的神奇用處使我不得不改變對(duì)機(jī)制的認(rèn)識(shí),本小節(jié)就帶大家重新學(xué)習(xí)一下機(jī)制吧。目前看來(lái),方法最具通用性。學(xué)習(xí)的方法論總而言之,因?yàn)橹匦聦W(xué)習(xí)方法的神奇用處與機(jī)制的例外情況,我得以修正上篇文章的錯(cuò)誤。 showImg(https://segmentfault.com/img/bVbkpfb?w=3106&h=2071);上篇文章《Python是否支持復(fù)制字符串呢?》剛發(fā)出一會(huì),...

    Towers 評(píng)論0 收藏0
  • join()方法神奇用處與Intern機(jī)制軟肋

    摘要:機(jī)制失效的情況方法的神奇用處使我不得不改變對(duì)機(jī)制的認(rèn)識(shí),本小節(jié)就帶大家重新學(xué)習(xí)一下機(jī)制吧。目前看來(lái),方法最具通用性。學(xué)習(xí)的方法論總而言之,因?yàn)橹匦聦W(xué)習(xí)方法的神奇用處與機(jī)制的例外情況,我得以修正上篇文章的錯(cuò)誤。 showImg(https://segmentfault.com/img/bVbkpfb?w=3106&h=2071);上篇文章《Python是否支持復(fù)制字符串呢?》剛發(fā)出一會(huì),...

    yck 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<