這篇文章給大家分享的是有關(guān)String.intern方法怎么用的內(nèi)容。小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過來(lái)看看吧。
創(chuàng)新互聯(lián)建站專注于烏拉特后企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站開發(fā),商城網(wǎng)站制作。烏拉特后網(wǎng)站建設(shè)公司,為烏拉特后等地區(qū)提供建站服務(wù)。全流程按需設(shè)計(jì),專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,創(chuàng)新互聯(lián)建站專業(yè)和態(tài)度為您提供的服務(wù)
記錄創(chuàng)建String的兩種方式,"" 和 new String()區(qū)別,String intern方法的使用和常量池。
package com.com.string; /** * @Auther: lantao * @Date: 2019-04-15 13:53 * @maill: lan_tao@suixingpay.com * @Description: TODO */ public class StringTest { public static void main(String[] args) { // 使用 "" 創(chuàng)建 會(huì)直接存儲(chǔ)在 常量池中 String a = "lantao"; // 使用 new String 創(chuàng)建, 會(huì)將zahngsan存儲(chǔ)到常量池中,然后在Heap中創(chuàng)建對(duì)象指向b String b = new String("zhangsan"); // 使用 字符串連接符拼接 ,會(huì)直接存儲(chǔ) 'wangwuzhaoliu' 字符串在常量池中 String c = "wangwu" + "zhaoliu"; // 使用字符串 "引用" 拼接 ,不執(zhí)行 intern 方法,不會(huì)存放到常量池中,但是會(huì)將 --- 存入到常量池中 String d = a + "---"; // 使用 new String 拼接 ,不執(zhí)行 intern 方法,不會(huì)存放到常量池中,但是會(huì)將wang 和 jiu 兩個(gè)字符串存到常量池中 String f = new String("wang") + "jiu"; // 使用 new String 拼接 ,不執(zhí)行 intern 方法,不會(huì)存放到常量池中, 但是會(huì)將 zhao 和 ba 兩個(gè)字符串存入到常量池中 String g = new String("zhao") + new String("ba"); } }
字符串拼接
public class StringTest { public static void main(String[] args) { String a = "lan" + "tao"; } }
lan 和 tao 都是字符串,都是在編譯器可知的,編譯器會(huì)將這行代碼優(yōu)化,當(dāng)一個(gè)字符串是由多個(gè)可知的字符串(非引用字符串)連接組成,將會(huì)優(yōu)化為如下。
public class StringTest { public static void main(String[] args) { String a = "lantao"; } }
JVM會(huì)將字符串"lantao"放入到String常量池中。
引用拼接:
public class StringTest { public static void main(String[] args) { String a = "lan"; String b = a + "tao"; // 上下含義相同 String c = "zhang"; String d = "san"; String f = c + d; } }
當(dāng)Java編譯器遇到字符串引用或 字符串引用和可知字符串拼接的時(shí)候,會(huì)創(chuàng)建一個(gè)StringBuilder
對(duì)象,后面的append()。
因?yàn)橛凶址么嬖?,而引用的值在程序編譯期是無(wú)法確定的。另外 "lan"、"tao" 都會(huì)編譯器添加到字符串常量池中(如果沒有的話),因?yàn)樗鼈兌际蔷幾g期確定的字符串常量,但是最后的"lantao"并不會(huì)添加到字符串常量池, 除非執(zhí)行b.intern() 方法
final拼接
public class StringTest { public static void main(String[] args) { final String a = "lan"; final String b = "tao"; String c = a + b + "2019"; } }
final拼接和以上兩者的區(qū)別就是在前邊增加了final修飾,用final修飾的字符串就是在編譯期可知的,編譯期就會(huì)將以上代碼優(yōu)化為
public class StringTest { public static void main(String[] args) { String str = "lantao2019"; } }
這里 final 拼接的效果是和字符串拼接是一致的。
變量a:"lantao" 是字符串常量,在編譯期就被確定了,先檢查字符串常量池中是否含有"lantao"字符串,若沒有則添加"lantao"到字符串常量池中,并且直接指向它。所以a直接指向字符串常量池的”lantao”,也就是變量a指向的地址是常量池中的 lantao。
變量b:用new String() 創(chuàng)建的字符串不是常量,不能在編譯期就確定,所以new String() 創(chuàng)建的字符串不放入常量池中,它們有自己的地址空間(Java Heap 中),變量b的引用的地址在Java Heap中。 但是"zhangsan"字符串常量在編譯期也會(huì)被加入到字符串常量池(如果常量池不存在的話)。
變量c:"wangwu"和"zhaoliu"也都是字符串常量,當(dāng)一個(gè)字符串由多個(gè)字符串常量連接而成時(shí),它自己肯定也是字符串常量,在編譯器會(huì)被編譯器優(yōu)化成"wangwuzhaoliu",所以c也同樣在編譯期就被解析為一個(gè)字符串常量,并且c是常量池中”wangwuzhaoliu”的一個(gè)引用,所以變量c的引用地址在常量池中。
變量d:JVM對(duì)于字符串引用,由于在字符串的”+”連接中,有字符串引用存在,而引用的值在程序編譯期是無(wú)法確定的,即`(a+"---")
變量f:變量f同樣不能在編譯期確定,但是"wang"和"jiu"這兩個(gè)字符串常量會(huì)添加到字符串常量池中,并且在堆中創(chuàng)建String對(duì)象。(字符串常量池并不會(huì)存放"wangjiu"這個(gè)字符串,除非執(zhí)行f.intern()方法)
變量g:同理變量f。
String.intern()是一個(gè)Native(本地)方法,它的作用是如果字符串常量池已經(jīng)包含一個(gè)等于此String對(duì)象的字符串,則返回字符串常量池中這個(gè)字符串的引用, 否則將當(dāng)前String對(duì)象的引用地址(堆中)添加到字符串常量池中并返回。
注意:基本數(shù)據(jù)類型之間的 == 是比較值,引用數(shù)據(jù)類型 == 比較的是地址值
public class StringTest { public static void main(String[] args) { // 基本數(shù)據(jù)類型之間的 == 是比較值,引用數(shù)據(jù)類型 == 比較的是地址值 // 1:在Java Heap中創(chuàng)建對(duì)象 2:在字符串常量池中添加 zhangsan String a = new String("zhangsan"); // 調(diào)用 intern 方法,因上一步中已經(jīng)將zhangsan存入常量池中,這里直接返回常量池 zhangsan 的引用地址 String b = a.intern(); // a 的地址在Java Heap中 , b的地址在 常量池中 ,所以結(jié)果是flase System.out.println(a == b); // 因?yàn)槌A砍刂幸呀?jīng)包含zhangsan,所以直接返回 String c = "zhangsan"; // b c 的地址一致,所以是true System.out.println(b == c); } } //結(jié)果 false true
解釋:
1:在Java Heap中創(chuàng)建對(duì)象然后在字符串常量池中添加zhangsan。
2:調(diào)用 intern方法,因上一步中已經(jīng)將zhangsan存入常量池中,這里直接返回常量池 zhangsan 的引用地址。
3:因 a 的地址在Heap中,b的地址在字符串常量池中。
4:因?yàn)槌A砍刂幸呀?jīng)包含zhangsan,所以直接返回
5: b c 的地址一致,所以是true
地址可以使用System.identityHashCode(a)方法獲取
public class StringTest { public static void main(String[] args) { //1: 首先會(huì)在Heap中創(chuàng)建對(duì)象,然后在常量池中放入zhagnsan 和 wangwu ,但是并不會(huì)放入zhagnsanwangwu String a = new String("zhangsan") + "wangwu"; // 2:調(diào)用 intern ,因?yàn)樽址A砍刂袥]有”zhangsanwangwu”這種拼接后的字符串,所以將堆中String對(duì)象的引用地址添加到字符串常量池中。jdk1.7后常量池引入到了Heap中,所以可以直接存儲(chǔ)引用 String b = a.intern(); // 3:因?yàn)?nbsp;a 的地址和 b的地址一致,鎖以是true System.out.println(a == b); //4:因常量池中已經(jīng)存在 zhangsanwangwu 了,所以直接返回引用就是 a 類型 a ==b 鎖 a==b==c String c = "zhangsanwangwu"; System.out.println(a == c); // true System.out.println(b == c); // true // 5:首先會(huì)在Heap中創(chuàng)建對(duì)象,然后會(huì)在常量池中存儲(chǔ) zhang 和 san String d = new String("zhang") + "san"; // 6: 返回的是 常量池中的 地址,因在a變量時(shí)已經(jīng)將 zhangsan 放入到了常量池中 String f = d.inter(); System.out.println(d = f); // false } }
解釋:
1:首先會(huì)在Heap中創(chuàng)建對(duì)象a,然后在常量池中放入zhagnsan 和 wangwu** ,但是并不會(huì)放入zhagnsanwangwu。
2:調(diào)用 intern ,因?yàn)樽址A砍刂袥]有”zhangsanwangwu”這種拼接后的字符串,所以將堆中String對(duì)象的引用地址添加到字符串常量池中。jdk1.7后常量池引入到了Heap中,所以可以直接存儲(chǔ)引用。
3:因?yàn)?a 的地址和 b的地址一致,所以是true。
4:因常量池中已經(jīng)存在 zhangsanwangwu了,所以直接返回引用就是 a 類型, a ==b 所以 a==b==c。
5:首先會(huì)在Heap中創(chuàng)建對(duì)象d,然后會(huì)在常量池中存儲(chǔ) zhang 和 san。
6:因在創(chuàng)建對(duì)象a時(shí),已經(jīng)將 "zhangsan"放入到了常量池,所以返回的是常量池中的zhangsan地址,對(duì)象d的地址在Heap中,f的地址在常量池中,并不是一個(gè),所以false;
感謝各位的閱讀!關(guān)于“String.intern方法怎么用”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!
本文名稱:String.intern方法怎么用
本文地址:http://jinyejixie.com/article14/ipjede.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供建站公司、品牌網(wǎng)站建設(shè)、網(wǎng)站建設(shè)、動(dòng)態(tài)網(wǎng)站、企業(yè)網(wǎng)站制作、微信公眾號(hào)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)