最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

解讀String字符串拼接的原理

 更新時(shí)間:2023年07月31日 16:26:08   作者:努力努力再努力c.  
這篇文章主要介紹了關(guān)于String字符串拼接的原理,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

前言

明白什么是引用,什么是該引用指向的真正對(duì)象。

==對(duì)于基本數(shù)據(jù)類型比較的是值,對(duì)于引用數(shù)據(jù)類型比較的是指向的對(duì)象的地址,即兩者指向的是否是同一個(gè)對(duì)象。

String s = "gzc";

上述代碼中s為變量引用,它存在于棧中,而“gzc”則是該變量引用所指向的真正數(shù)據(jù),它存在于字符串常量池中。

言歸正傳

字符串拼接主要有2種情況:

1、常量與常量拼接

String s1 = "g"+"zc";//常量“g”與常量“zc”拼接

常量與常量拼接的原理:

字符串常量與常量之間的拼接操作其實(shí)在未加載到JVM內(nèi)存之前就已經(jīng)完成了,即在編譯期間就會(huì)對(duì)字符串常量之間的拼接操作進(jìn)行優(yōu)化如下圖,

進(jìn)行反編譯后,我們不難發(fā)現(xiàn)在編譯完之后,s4已經(jīng)被直接拼接好了。而且此時(shí)s3和s4指向的是字符串常量池中的同一個(gè)對(duì)象,即兩者存儲(chǔ)的對(duì)象地址是相同的。

所以s3==s4其結(jié)果為true。

2、涉及到變量的字符串拼接

2.1 變量與常量拼接

String s1 = "g";
String s2 = s1+"zc";//變量s1與常量“zc”拼接

2.2 變量與變量拼接

String s1 = "g";
String s2 = "zc";
String s3 = s1+s2;//變量s1與變量s2拼接

涉及到變量的字符串拼接原理:

只要字符串拼接其中涉及到變量,不管是幾個(gè)變量,那么其拼接原理都如下:

當(dāng)涉及到變量時(shí),字符串用+進(jìn)行字符串拼接的本質(zhì),其實(shí)就是利用StringBuilder類里的append()方法,將每一個(gè)字符串都一一添加進(jìn)去,然后返回一個(gè)StringBuilder對(duì)象,所以可以不用新創(chuàng)建一個(gè)對(duì)象去接收返回值,直接鏈?zhǔn)骄幊痰玫阶罱K添加的結(jié)果,最后再調(diào)用toString()方法將其轉(zhuǎn)換為我們想要的字符串String類型。

如下圖:

特別注意:

StringBuilder的toString()方法調(diào)用的是String重載的構(gòu)造器方法,是以字符數(shù)組為字符串實(shí)際內(nèi)容進(jìn)行創(chuàng)建的,并未直接以字面量方式創(chuàng)建String對(duì)象,即:

所以如果我們上述代碼沒(méi)有定義s3和s4兩個(gè)變量,只定義了String s5 = s1+s2; 的話,那么其實(shí)字符串常量池中是不存在“gzc”這個(gè)字符串的,而是只有“g”和“zc”。

因?yàn)橹挥型ㄟ^(guò)字面量定義一個(gè)字符串以及調(diào)用String的intern()方法,這兩種方式才會(huì)在字符串常量池中生成對(duì)應(yīng)的對(duì)象。

而StringBuilder調(diào)用toString()方法創(chuàng)建的String對(duì)象則會(huì)直接在堆中為其分配內(nèi)存,常量池中不會(huì)存在對(duì)應(yīng)的對(duì)象。

所以如果判斷s3==s5,則結(jié)果為false,因?yàn)閟3指向的是字符串常量池中的“gzc”,而s5指向的是堆中的“gzc”對(duì)象,二者指向的對(duì)象地址不同,則比較結(jié)果自然為false。

特殊情況

若變量被聲明為final類型,即為常量,則就遵循字符串常量拼接的規(guī)則了。

如下圖:

jdk 1.8 對(duì)String字符串拼接并沒(méi)有優(yōu)化

String s = new String("1") + new String("1");
		String s2 = s + "1" + "1" + "1";
		//String s = "1" + "1";
		String s1 = "11";
		System.out.println(s.intern() == s1);
public static void main(java.lang.String[] args);
     0  new java.lang.StringBuilder [16]
     3  dup
     4  new java.lang.String [18]
     7  dup
     8  ldc <String "1"> [20]
    10  invokespecial java.lang.String(java.lang.String) [22]
    13  invokestatic java.lang.String.valueOf(java.lang.Object) : java.lang.String [25]
    16  invokespecial java.lang.StringBuilder(java.lang.String) [29]
    19  new java.lang.String [18]
    22  dup
    23  ldc <String "1"> [20]
    25  invokespecial java.lang.String(java.lang.String) [22]
    28  invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [30]
    31  invokevirtual java.lang.StringBuilder.toString() : java.lang.String [34]
    34  astore_1 [s]
    35  new java.lang.StringBuilder [16]
    38  dup
    39  aload_1 [s]
    40  invokestatic java.lang.String.valueOf(java.lang.Object) : java.lang.String [25]
    43  invokespecial java.lang.StringBuilder(java.lang.String) [29]
    46  ldc <String "1"> [20]
    48  invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [30]
    51  ldc <String "1"> [20]
    53  invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [30]
    56  ldc <String "1"> [20]
    58  invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [30]
    61  invokevirtual java.lang.StringBuilder.toString() : java.lang.String [34]
    64  astore_2 [s2]
    65  ldc <String "11"> [38]
    67  astore_3 [s1]
    68  getstatic java.lang.System.out : java.io.PrintStream [40]
    71  aload_1 [s]
    72  invokevirtual java.lang.String.intern() : java.lang.String [46]
    75  aload_3 [s1]
    76  if_acmpne 83
    79  iconst_1
    80  goto 84
    83  iconst_0
    84  invokevirtual java.io.PrintStream.println(boolean) : void [49]
    87  return
      Line numbers:
        [pc: 0, line: 18]
        [pc: 35, line: 19]
        [pc: 65, line: 21]
        [pc: 68, line: 22]
        [pc: 87, line: 23]
      Local variable table:
        [pc: 0, pc: 88] local: args index: 0 type: java.lang.String[]
        [pc: 35, pc: 88] local: s index: 1 type: java.lang.String
        [pc: 65, pc: 88] local: s2 index: 2 type: java.lang.String
        [pc: 68, pc: 88] local: s1 index: 3 type: java.lang.String
      Stack map table: number of frames 2
        [pc: 83, full, stack: {java.io.PrintStream}, locals: {java.lang.String[], java.lang.String, java.lang.String, java.lang.String}]
        [pc: 84, full, stack: {java.io.PrintStream, int}, locals: {java.lang.String[], java.lang.String, java.lang.String, java.lang.String}]
}

從class文件中可以看出,依然new了兩個(gè)stringBuilder對(duì)象

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java中的HashSet集合解析

    Java中的HashSet集合解析

    這篇文章主要介紹了Java中的HashSet集合解析,HashSet 實(shí)現(xiàn) Set 接口,內(nèi)部維護(hù)一個(gè) HashMap 實(shí)例,它不能保證集合迭代的順序,也不能保證順序不變,HashSet 允許 null 元素,需要的朋友可以參考下
    2023-11-11
  • SpringSecurity Demo 創(chuàng)建項(xiàng)目的過(guò)程詳解

    SpringSecurity Demo 創(chuàng)建項(xiàng)目的過(guò)程詳解

    本文介紹了使用SpringBoot 3.2.4創(chuàng)建一個(gè)簡(jiǎn)單的安全驗(yàn)證項(xiàng)目的過(guò)程,包括引入依賴、配置文件修改、創(chuàng)建控制器和啟動(dòng)類等步驟,并最終成功啟動(dòng)項(xiàng)目并在瀏覽器訪問(wèn)到請(qǐng)求接口,感興趣的朋友跟隨小編一起看看吧
    2026-04-04
  • 一篇文章看懂Java字符串操作

    一篇文章看懂Java字符串操作

    String是Java中的類,它提供一些預(yù)定義的方法,這些方法使基于字符串的問(wèn)題解決方案更加容易,下面這篇文章主要給大家介紹了關(guān)于Java字符串操作的相關(guān)資料,需要的朋友可以參考下
    2021-11-11
  • 解決mybatis中resultType取出數(shù)據(jù)順序不一致的問(wèn)題

    解決mybatis中resultType取出數(shù)據(jù)順序不一致的問(wèn)題

    這篇文章主要介紹了解決mybatis中resultType取出數(shù)據(jù)順序不一致的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • java實(shí)現(xiàn)折半排序算法

    java實(shí)現(xiàn)折半排序算法

    折半插入排序法,又稱二分插入排序法,是直接插入排序法的改良版,也需要執(zhí)行i-1趟插入,不同之處在于,第i趟插入,先找出第i+1個(gè)元素應(yīng)該插入的的位置,假定前i個(gè)數(shù)據(jù)是已經(jīng)處于有序狀態(tài)。
    2015-04-04
  • 使用Java編寫控制JDBC連接、執(zhí)行及關(guān)閉的工具類

    使用Java編寫控制JDBC連接、執(zhí)行及關(guān)閉的工具類

    這篇文章主要介紹了如何使用Java來(lái)編寫控制JDBC連接、執(zhí)行及關(guān)閉的程序,包括一個(gè)針對(duì)各種數(shù)據(jù)庫(kù)通用的釋放資源的工具類的寫法,需要的朋友可以參考下
    2016-03-03
  • Java 代碼檢查工具之PMD入門使用詳細(xì)教程

    Java 代碼檢查工具之PMD入門使用詳細(xì)教程

    這篇文章主要介紹了Java 代碼檢查工具之PMD入門使用詳細(xì)教程,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • 淺析java雙向冒泡排序算法

    淺析java雙向冒泡排序算法

    這篇文章主要介紹了淺析java雙向冒泡排序算法,并附上源碼,需要的朋友可以參考下
    2015-02-02
  • macOS上使用gperftools定位Java內(nèi)存泄漏問(wèn)題及解決方案

    macOS上使用gperftools定位Java內(nèi)存泄漏問(wèn)題及解決方案

    這篇文章主要介紹了macOS上使用gperftools定位Java內(nèi)存泄漏問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-07-07
  • Java設(shè)計(jì)模式之原型設(shè)計(jì)示例詳解

    Java設(shè)計(jì)模式之原型設(shè)計(jì)示例詳解

    這篇文章主要為大家詳細(xì)介紹了Java的原型設(shè)計(jì)模式,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-03-03

最新評(píng)論

黄浦区| 武隆县| 六盘水市| 冷水江市| 尤溪县| 波密县| 宝清县| 庆元县| 西吉县| 阿城市| 隆化县| 河东区| 安泽县| 葵青区| 澎湖县| 乐至县| 万源市| 高青县| 东阿县| 西乌珠穆沁旗| 神木县| 富源县| 福鼎市| 乌审旗| 张掖市| 大足县| 保康县| 太保市| 宜黄县| 江口县| 宝应县| 美姑县| 铜鼓县| 板桥市| 厦门市| 璧山县| 浮梁县| 大渡口区| 鲜城| 通江县| 克拉玛依市|