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

資訊專欄INFORMATION COLUMN

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

derek_334892 / 3901人閱讀

摘要:對比較返回是因為這個字符串在執(zhí)之前已經(jīng)出現(xiàn)過,字符串常量池中已經(jīng)有它的引用了,不符合首次出現(xiàn)的原則,而計算機軟件這個字符串則是首次出現(xiàn)的,因此返回。

在《深入理解Java虛擬機》書中,提到在jdk1.7的版本中用String.intern()返回引用。

public class RuntimeConstantPoolOOM {
    public static void main(String[]args) {
        String str1=new StringBuilder("計算機").append("軟件").toString();
        System.out.println(str1.intern()==str1);
        String str2=new StringBuilder("ja").append("va").toString();
        System.out.println(str2.intern()==str2);
    }

}

運行結(jié)果:true false
書中給的解釋是:

JDK 1.7(以及部分其他虛擬機,例如JRockit)的intern()實現(xiàn)不會再復制實例,只是在常量池中記錄首次出現(xiàn)的實例引用,因此intern()返回的引用和由StringBuilder創(chuàng)建的那個字符串實例是同一個。對str2比較返回false是因為“java”這個字符串在執(zhí)StringBuilder.toString()之前已經(jīng)出現(xiàn)過,字符串常量池中已經(jīng)有它的引用了,不符合“首次出現(xiàn)”的原則,而“計算機軟件”這個字符串則是首次出現(xiàn)的,因此返回true。

現(xiàn)在的疑問是“java”這個字符串在常量池中什么時候存在了?
我最開始的猜想是“java”這個字符串是不是常駐在常量池中的?那為什么常駐在常量池中呢?Java虛擬機什么時候加載了“java”這個字符串?

最開始以為是StringBuilder的原因,查看了一下StringBuilder的源碼,發(fā)現(xiàn)里面沒有加載字符串常量,網(wǎng)上也找了關(guān)于intern()的,發(fā)現(xiàn)都只是對比JDK 1.6和JDK 1.7之間上面代碼的運行結(jié)果比較,后來找了許久,終于找到一篇關(guān)于[String.intern()探究]: 的文章,發(fā)現(xiàn)要去查看System的源碼.

java虛擬機會自動調(diào)用System類

/* register the natives via the static initializer.
 *
 * VM will invoke the initializeSystemClass method to complete
 * the initialization for this class separated from clinit.
 * Note that to use properties set by the VM, see the constraints
 * described in the initializeSystemClass method.
 */
在System類中的注釋可以知道,調(diào)用了initializeSystemClass方法,在此方法中調(diào)用了Version對象的init靜態(tài)方法
sun.misc.Version.init();
因此sun.misc.Version類會在JDK類庫的初始化過程中被加載并初始化。
查看Version類定義的私有靜態(tài)字符串常量如下:
private static final String launcher_name = "java";
private static final String java_version = "1.7.0_51";
private static final String java_runtime_name = "Java(TM) SE Runtime Environment";
private static final String java_runtime_version = "1.7.0_51-b13";
在初始化Version類時,對其靜態(tài)常量字段根據(jù)指定的常量值做默認初始化,所以"java"被加載到了字符串常量池中,修改上面代碼使字符串值為上面常量中的任意一個都會返回false。
String str2=new StringBuilder("1.7.0").append("_51").toString();
System.out.println(str2.intern()==str2);

這個問題解決了,然后我又發(fā)現(xiàn)了另外一個問題。除了這些在虛擬機加載時就初始化的常量,定義其他的字符串常量,比如“nihao”.

先運行這個代碼
String str3 = new StringBuilder("ni").append("hao").toString();
System.out.println(str3==str3.intern());
通過上面的解釋,運行結(jié)果為true.
在運行這個代碼
String str3 = new StringBuilder("nihao").toString();
System.out.println(str3==str3.intern());
其結(jié)果是什么?應該還是true吧,畢竟通過上一個運行結(jié)果可以知道"nihao"這個字符串常量沒有被預先加載到常量池中。
但是運行結(jié)果卻是false.

我現(xiàn)在還沒想通這個問題,StringBuilder的append方法沒有改變字符串的引用地址,只是把其值改變了,為什么加了append返回的是true,沒有加append卻是false呢?如果在后面多加幾個append返回的也是true。
也希望有人可以解答一下這個問題

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

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

相關(guān)文章

  • String的內(nèi)存模型,為什么String被設計成不可變的

    摘要:證明返回常量池中已存在的對象,不等于新建的對象。為什么要設計成一下內(nèi)容來自發(fā)現(xiàn)百度的中文版本基本也是此文的翻譯版??傊?,安全性和字符串常量池緩存是被設計成不可變的主要原因。 String是Java中最常用的類,是不可變的(Immutable), 那么String是如何實現(xiàn)Immutable呢,String為什么要設計成不可變呢? 前言 關(guān)于String,收集一波基礎,來源標明最后,不確...

    vspiders 評論0 收藏0
  • 關(guān)于 String.intern() 的思考

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

    siberiawolf 評論0 收藏0
  • 深入研究Java String

    摘要:所以我決定先從類入手,深入的研究一番來開個好頭。之所以會有以上的效果,是因為有字符串常量池的存在。同時運行時實例創(chuàng)建的全局字符串常量池中有一個表,總是為池中的每個字符串對象維護一個引用,所以這些對象不會被。 開始寫 Java 一年來,一直都是遇到什么問題再去解決,還沒有主動的深入的去學習過 Java 語言的特性和深入閱讀 JDK 的源碼。既然決定今后靠 Java吃飯,還是得花些心思在上...

    番茄西紅柿 評論0 收藏0
  • Java內(nèi)存區(qū)域及內(nèi)存溢出

    摘要:直接通過可以造成本機內(nèi)存溢出。小節(jié)內(nèi)存區(qū)域描述異常程序計數(shù)器略略略虛擬機棧存放編譯器可知的各種基本類型,對象引用和類型每個線程的棧大小堆存放對象實例最大值最小值運行時常亮池存放編譯期生成的字面量和符號引用,運行期也能放入常量池。 堆溢出 Java堆用于存儲對象實例,只要不斷地創(chuàng)建對象,并且保證GC Roots到對象之間有可達路徑避免垃圾回收,當?shù)竭_最大堆的容量限制后就會產(chǎn)生Java.l...

    cheukyin 評論0 收藏0
  • 為什么不建議在for循環(huán)中使用"+"進行字符串拼接

    摘要:使用可以方便的對字符串進行拼接。該方法使用進行聲明,說明是一個線程安全的方法。所以,阿里巴巴開發(fā)手冊建議循環(huán)體內(nèi),字符串的連接方式,使用的方法進行擴展。但是,還要強調(diào)的是如果不是在循環(huán)體中進行字符串拼接的話,直接使用就好了。 摘要: 學習阿里巴巴Java開發(fā)手冊。 原文:為什么阿里巴巴不建議在for循環(huán)中使用+進行字符串拼接 微信公眾號:Hollis Fundebug經(jīng)授權(quán)轉(zhuǎn)載,...

    caoym 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<