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

關(guān)于java String中intern的深入講解

 更新時(shí)間:2019年04月07日 08:41:30   作者:codecraft  
這篇文章主要給大家介紹了關(guān)于java String中intern的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧


本文主要研究一下java String的intern

String.intern()

java.base/java/lang/String.java

public final class String
 implements java.io.Serializable, Comparable<String>, CharSequence,
    Constable, ConstantDesc {

 //......

 /**
  * Returns a canonical representation for the string object.
  * <p>
  * A pool of strings, initially empty, is maintained privately by the
  * class {@code String}.
  * <p>
  * When the intern method is invoked, if the pool already contains a
  * string equal to this {@code String} object as determined by
  * the {@link #equals(Object)} method, then the string from the pool is
  * returned. Otherwise, this {@code String} object is added to the
  * pool and a reference to this {@code String} object is returned.
  * <p>
  * It follows that for any two strings {@code s} and {@code t},
  * {@code s.intern() == t.intern()} is {@code true}
  * if and only if {@code s.equals(t)} is {@code true}.
  * <p>
  * All literal strings and string-valued constant expressions are
  * interned. String literals are defined in section 3.10.5 of the
  * <cite>The Java&trade; Language Specification</cite>.
  *
  * @return a string that has the same contents as this string, but is
  *   guaranteed to be from a pool of unique strings.
  * @jls 3.10.5 String Literals
  */
 public native String intern();

 //......   

}    
  • 當(dāng)調(diào)用intern方法時(shí),如果常量池已經(jīng)包含一個(gè)equals此String對象的字符串,則返回池中的字符串
  • 當(dāng)調(diào)用intern方法時(shí),如果常量池沒有一個(gè)equals此String對象的字符串,將此String對象添加到池中,并返回此String對象的引用(即intern方法返回指向heap中的此String對象引用)
  • 所有l(wèi)iteral strings及string-valued constant expressions都是interned的

實(shí)例

基于jdk12

StringExistInPoolBeforeIntern

public class StringExistInPoolBeforeIntern {

 public static void main(String[] args){
  String stringObject = new String("tomcat");
  //NOTE 在intern之前,string table已經(jīng)有了tomcat,因而intern返回tomcat,不會(huì)指向stringObject
  stringObject.intern();
  String stringLiteral = "tomcat";
  System.out.println(stringObject == stringLiteral); //false
 }
}
  • tomcat這個(gè)literal string是interned過的,常量池沒有tomcat,因而添加到常量池,常量池有個(gè)tomcat;另外由于stringObject是new的,所以heap中也有一個(gè)tomcat,而此時(shí)它指向heap中的tomcat
  • stringObject.intern()返回的是heap中常量池的tomcat;stringLiteral是tomcat這個(gè)literal string,由于常量池已經(jīng)有該值,因而stringLiteral指向的是heap中常量池的tomcat
  • 此時(shí)stringObject指向的是heap中的tomcat,而stringLiteral是heap中常量池的tomcat,因而二者不等,返回false

StringNotExistInPoolBeforeIntern

public class StringNotExistInPoolBeforeIntern {

 public static void main(String[] args){
  String stringObject = new String("tom") + new String("cat");
  //NOTE 在intern之前,string table沒有tomcat,因而intern指向stringObject
  stringObject.intern();
  String stringLiteral = "tomcat";
  System.out.println(stringObject == stringLiteral); //true
 }
}
  • tom及cat這兩個(gè)literal string是interned過的,常量池沒有tom及cat,因而添加到常量池,常量池有tom、cat;另外由于stringObject是new出來的,是tom及cat二者concat,因而heap中有一個(gè)tomcat
  • stringObject的intern方法執(zhí)行的時(shí)候,由于常量池中沒有tomcat,因而添加到常量池,intern()返回的是指向heap中的tomcat的引用;stringLiteral是tomcat這個(gè)literal string,由于stringObject.intern()已經(jīng)將tomcat添加到常量池了并指向heap中的tomcat的引用,所以stringLiteral返回的是指向heap中的tomcat的引用
  • 由于stringLiteral返回的是指向heap中的tomcat的引用,其實(shí)就是stringObject,因而二者相等,返回true

javap

基于jdk12

StringExistInPoolBeforeIntern

javac src/main/java/com/example/javac/StringExistInPoolBeforeIntern.java
javap -v src/main/java/com/example/javac/StringExistInPoolBeforeIntern.class

 Last modified 2019年4月6日; size 683 bytes
 MD5 checksum 207635ffd7560f1df24b98607e2ca7db
 Compiled from "StringExistInPoolBeforeIntern.java"
public class com.example.javac.StringExistInPoolBeforeIntern
 minor version: 0
 major version: 56
 flags: (0x0021) ACC_PUBLIC, ACC_SUPER
 this_class: #8       // com/example/javac/StringExistInPoolBeforeIntern
 super_class: #9       // java/lang/Object
 interfaces: 0, fields: 0, methods: 2, attributes: 1
Constant pool:
 #1 = Methodref   #9.#21   // java/lang/Object."<init>":()V
 #2 = Class    #22   // java/lang/String
 #3 = String    #23   // tomcat
 #4 = Methodref   #2.#24   // java/lang/String."<init>":(Ljava/lang/String;)V
 #5 = Methodref   #2.#25   // java/lang/String.intern:()Ljava/lang/String;
 #6 = Fieldref   #26.#27  // java/lang/System.out:Ljava/io/PrintStream;
 #7 = Methodref   #18.#28  // java/io/PrintStream.println:(Z)V
 #8 = Class    #29   // com/example/javac/StringExistInPoolBeforeIntern
 #9 = Class    #30   // java/lang/Object
 #10 = Utf8    <init>
 #11 = Utf8    ()V
 #12 = Utf8    Code
 #13 = Utf8    LineNumberTable
 #14 = Utf8    main
 #15 = Utf8    ([Ljava/lang/String;)V
 #16 = Utf8    StackMapTable
 #17 = Class    #31   // "[Ljava/lang/String;"
 #18 = Class    #32   // java/io/PrintStream
 #19 = Utf8    SourceFile
 #20 = Utf8    StringExistInPoolBeforeIntern.java
 #21 = NameAndType  #10:#11  // "<init>":()V
 #22 = Utf8    java/lang/String
 #23 = Utf8    tomcat
 #24 = NameAndType  #10:#33  // "<init>":(Ljava/lang/String;)V
 #25 = NameAndType  #34:#35  // intern:()Ljava/lang/String;
 #26 = Class    #36   // java/lang/System
 #27 = NameAndType  #37:#38  // out:Ljava/io/PrintStream;
 #28 = NameAndType  #39:#40  // println:(Z)V
 #29 = Utf8    com/example/javac/StringExistInPoolBeforeIntern
 #30 = Utf8    java/lang/Object
 #31 = Utf8    [Ljava/lang/String;
 #32 = Utf8    java/io/PrintStream
 #33 = Utf8    (Ljava/lang/String;)V
 #34 = Utf8    intern
 #35 = Utf8    ()Ljava/lang/String;
 #36 = Utf8    java/lang/System
 #37 = Utf8    out
 #38 = Utf8    Ljava/io/PrintStream;
 #39 = Utf8    println
 #40 = Utf8    (Z)V
{
 public com.example.javac.StringExistInPoolBeforeIntern();
 descriptor: ()V
 flags: (0x0001) ACC_PUBLIC
 Code:
  stack=1, locals=1, args_size=1
   0: aload_0
   1: invokespecial #1     // Method java/lang/Object."<init>":()V
   4: return
  LineNumberTable:
  line 8: 0

 public static void main(java.lang.String[]);
 descriptor: ([Ljava/lang/String;)V
 flags: (0x0009) ACC_PUBLIC, ACC_STATIC
 Code:
  stack=3, locals=3, args_size=1
   0: new   #2     // class java/lang/String
   3: dup
   4: ldc   #3     // String tomcat
   6: invokespecial #4     // Method java/lang/String."<init>":(Ljava/lang/String;)V
   9: astore_1
  10: aload_1
  11: invokevirtual #5     // Method java/lang/String.intern:()Ljava/lang/String;
  14: pop
  15: ldc   #3     // String tomcat
  17: astore_2
  18: getstatic  #6     // Field java/lang/System.out:Ljava/io/PrintStream;
  21: aload_1
  22: aload_2
  23: if_acmpne  30
  26: iconst_1
  27: goto   31
  30: iconst_0
  31: invokevirtual #7     // Method java/io/PrintStream.println:(Z)V
  34: return
  LineNumberTable:
  line 11: 0
  line 13: 10
  line 14: 15
  line 15: 18
  line 16: 34
  StackMapTable: number_of_entries = 2
  frame_type = 255 /* full_frame */
   offset_delta = 30
   locals = [ class "[Ljava/lang/String;", class java/lang/String, class java/lang/String ]
   stack = [ class java/io/PrintStream ]
  frame_type = 255 /* full_frame */
   offset_delta = 0
   locals = [ class "[Ljava/lang/String;", class java/lang/String, class java/lang/String ]
   stack = [ class java/io/PrintStream, int ]
}
SourceFile: "StringExistInPoolBeforeIntern.java"
  • 可以看到常量池有個(gè)tomcat

StringNotExistInPoolBeforeIntern

javac src/main/java/com/example/javac/StringNotExistInPoolBeforeIntern.java
javap -v src/main/java/com/example/javac/StringNotExistInPoolBeforeIntern.class

 Last modified 2019年4月6日; size 1187 bytes
 MD5 checksum 6d173f303b61b8f5826e54bb6ed5157c
 Compiled from "StringNotExistInPoolBeforeIntern.java"
public class com.example.javac.StringNotExistInPoolBeforeIntern
 minor version: 0
 major version: 56
 flags: (0x0021) ACC_PUBLIC, ACC_SUPER
 this_class: #11       // com/example/javac/StringNotExistInPoolBeforeIntern
 super_class: #12      // java/lang/Object
 interfaces: 0, fields: 0, methods: 2, attributes: 3
Constant pool:
 #1 = Methodref   #12.#24  // java/lang/Object."<init>":()V
 #2 = Class    #25   // java/lang/String
 #3 = String    #26   // tom
 #4 = Methodref   #2.#27   // java/lang/String."<init>":(Ljava/lang/String;)V
 #5 = String    #28   // cat
 #6 = InvokeDynamic  #0:#32   // #0:makeConcatWithConstants:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 #7 = Methodref   #2.#33   // java/lang/String.intern:()Ljava/lang/String;
 #8 = String    #34   // tomcat
 #9 = Fieldref   #35.#36  // java/lang/System.out:Ljava/io/PrintStream;
 #10 = Methodref   #21.#37  // java/io/PrintStream.println:(Z)V
 #11 = Class    #38   // com/example/javac/StringNotExistInPoolBeforeIntern
 #12 = Class    #39   // java/lang/Object
 #13 = Utf8    <init>
 #14 = Utf8    ()V
 #15 = Utf8    Code
 #16 = Utf8    LineNumberTable
 #17 = Utf8    main
 #18 = Utf8    ([Ljava/lang/String;)V
 #19 = Utf8    StackMapTable
 #20 = Class    #40   // "[Ljava/lang/String;"
 #21 = Class    #41   // java/io/PrintStream
 #22 = Utf8    SourceFile
 #23 = Utf8    StringNotExistInPoolBeforeIntern.java
 #24 = NameAndType  #13:#14  // "<init>":()V
 #25 = Utf8    java/lang/String
 #26 = Utf8    tom
 #27 = NameAndType  #13:#42  // "<init>":(Ljava/lang/String;)V
 #28 = Utf8    cat
 #29 = Utf8    BootstrapMethods
 #30 = MethodHandle  6:#43   // REF_invokeStatic java/lang/invoke/StringConcatFactory.makeConcatWithConstants:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
 #31 = String    #44   // \u0001\u0001
 #32 = NameAndType  #45:#46  // makeConcatWithConstants:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 #33 = NameAndType  #47:#48  // intern:()Ljava/lang/String;
 #34 = Utf8    tomcat
 #35 = Class    #49   // java/lang/System
 #36 = NameAndType  #50:#51  // out:Ljava/io/PrintStream;
 #37 = NameAndType  #52:#53  // println:(Z)V
 #38 = Utf8    com/example/javac/StringNotExistInPoolBeforeIntern
 #39 = Utf8    java/lang/Object
 #40 = Utf8    [Ljava/lang/String;
 #41 = Utf8    java/io/PrintStream
 #42 = Utf8    (Ljava/lang/String;)V
 #43 = Methodref   #54.#55  // java/lang/invoke/StringConcatFactory.makeConcatWithConstants:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
 #44 = Utf8    \u0001\u0001
 #45 = Utf8    makeConcatWithConstants
 #46 = Utf8    (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 #47 = Utf8    intern
 #48 = Utf8    ()Ljava/lang/String;
 #49 = Utf8    java/lang/System
 #50 = Utf8    out
 #51 = Utf8    Ljava/io/PrintStream;
 #52 = Utf8    println
 #53 = Utf8    (Z)V
 #54 = Class    #56   // java/lang/invoke/StringConcatFactory
 #55 = NameAndType  #45:#60  // makeConcatWithConstants:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
 #56 = Utf8    java/lang/invoke/StringConcatFactory
 #57 = Class    #62   // java/lang/invoke/MethodHandles$Lookup
 #58 = Utf8    Lookup
 #59 = Utf8    InnerClasses
 #60 = Utf8    (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
 #61 = Class    #63   // java/lang/invoke/MethodHandles
 #62 = Utf8    java/lang/invoke/MethodHandles$Lookup
 #63 = Utf8    java/lang/invoke/MethodHandles
{
 public com.example.javac.StringNotExistInPoolBeforeIntern();
 descriptor: ()V
 flags: (0x0001) ACC_PUBLIC
 Code:
  stack=1, locals=1, args_size=1
   0: aload_0
   1: invokespecial #1     // Method java/lang/Object."<init>":()V
   4: return
  LineNumberTable:
  line 8: 0

 public static void main(java.lang.String[]);
 descriptor: ([Ljava/lang/String;)V
 flags: (0x0009) ACC_PUBLIC, ACC_STATIC
 Code:
  stack=4, locals=3, args_size=1
   0: new   #2     // class java/lang/String
   3: dup
   4: ldc   #3     // String tom
   6: invokespecial #4     // Method java/lang/String."<init>":(Ljava/lang/String;)V
   9: new   #2     // class java/lang/String
  12: dup
  13: ldc   #5     // String cat
  15: invokespecial #4     // Method java/lang/String."<init>":(Ljava/lang/String;)V
  18: invokedynamic #6, 0    // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
  23: astore_1
  24: aload_1
  25: invokevirtual #7     // Method java/lang/String.intern:()Ljava/lang/String;
  28: pop
  29: ldc   #8     // String tomcat
  31: astore_2
  32: getstatic  #9     // Field java/lang/System.out:Ljava/io/PrintStream;
  35: aload_1
  36: aload_2
  37: if_acmpne  44
  40: iconst_1
  41: goto   45
  44: iconst_0
  45: invokevirtual #10     // Method java/io/PrintStream.println:(Z)V
  48: return
  LineNumberTable:
  line 11: 0
  line 13: 24
  line 14: 29
  line 15: 32
  line 16: 48
  StackMapTable: number_of_entries = 2
  frame_type = 255 /* full_frame */
   offset_delta = 44
   locals = [ class "[Ljava/lang/String;", class java/lang/String, class java/lang/String ]
   stack = [ class java/io/PrintStream ]
  frame_type = 255 /* full_frame */
   offset_delta = 0
   locals = [ class "[Ljava/lang/String;", class java/lang/String, class java/lang/String ]
   stack = [ class java/io/PrintStream, int ]
}
SourceFile: "StringNotExistInPoolBeforeIntern.java"
InnerClasses:
 public static final #58= #57 of #61; // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
BootstrapMethods:
 0: #30 REF_invokeStatic java/lang/invoke/StringConcatFactory.makeConcatWithConstants:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
 Method arguments:
  #31 \u0001\u0001

可以看到常量池有tom、cat、tomcat

小結(jié)

當(dāng)調(diào)用intern方法時(shí),如果常量池已經(jīng)包含一個(gè)equals此String對象的字符串,則返回池中的字符串
當(dāng)調(diào)用intern方法時(shí),如果常量池沒有一個(gè)equals此String對象的字符串,將此String對象添加到池中,并返回此String對象的引用(即intern方法返回指向heap中的此String對象引用)

所有l(wèi)iteral strings及string-valued constant expressions都是interned的

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對腳本之家的支持。

相關(guān)文章

  • 如何使用BufferedReader循環(huán)讀文件

    如何使用BufferedReader循環(huán)讀文件

    這篇文章主要介紹了如何使用BufferedReader循環(huán)讀文件的操作,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Mac Book中Java環(huán)境變量設(shè)置的方法

    Mac Book中Java環(huán)境變量設(shè)置的方法

    本文給大家介紹mac book 中設(shè)置java環(huán)境變量的方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下
    2017-04-04
  • springboot整合RabbitMQ 中的 TTL實(shí)例代碼

    springboot整合RabbitMQ 中的 TTL實(shí)例代碼

    TTL 是 RabbitMQ 中一個(gè)消息或者隊(duì)列的屬性,表明一條消息或者該隊(duì)列中的所有消息的最大存活時(shí)間,單位是毫秒,這篇文章主要介紹了springboot整合RabbitMQ 中的 TTL,需要的朋友可以參考下
    2022-09-09
  • Java拆箱與裝箱實(shí)例詳解

    Java拆箱與裝箱實(shí)例詳解

    這篇文章主要介紹了Java拆箱與裝箱,結(jié)合實(shí)例形式詳細(xì)分析了Java拆箱與裝箱相關(guān)的數(shù)據(jù)類型轉(zhuǎn)換操作技巧,需要的朋友可以參考下
    2019-11-11
  • 項(xiàng)目總結(jié)之HttpURLConnection的disconnect的問題

    項(xiàng)目總結(jié)之HttpURLConnection的disconnect的問題

    這篇文章主要介紹了項(xiàng)目總結(jié)之HttpURLConnection的disconnect的問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • Mybatis中多個(gè)對象包含同一個(gè)對象的處理操作

    Mybatis中多個(gè)對象包含同一個(gè)對象的處理操作

    這篇文章主要介紹了Mybatis中多個(gè)對象包含同一個(gè)對象的處理操作,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • java對list<Object>進(jìn)行手動(dòng)分頁實(shí)現(xiàn)

    java對list<Object>進(jìn)行手動(dòng)分頁實(shí)現(xiàn)

    本文主要介紹了java對list<Object>進(jìn)行手動(dòng)分頁實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • Java語言實(shí)現(xiàn)快速冪取模算法詳解

    Java語言實(shí)現(xiàn)快速冪取模算法詳解

    這篇文章主要介紹了Java語言實(shí)現(xiàn)快速冪取模算法詳解,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • java計(jì)算值所占的百分比,結(jié)果為100%問題

    java計(jì)算值所占的百分比,結(jié)果為100%問題

    這篇文章主要介紹了java計(jì)算值所占的百分比,結(jié)果為100%問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • 詳談Spring對IOC的理解(推薦篇)

    詳談Spring對IOC的理解(推薦篇)

    下面小編就為大家?guī)硪黄斦凷pring對IOC的理解(推薦篇)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-10-10

最新評論

昭通市| 桑日县| 乌兰浩特市| 万年县| 米泉市| 昌吉市| 伽师县| 改则县| 新郑市| 张家港市| 平顺县| 台北县| 高雄县| 东源县| 当涂县| 连城县| 临洮县| 六枝特区| 浮梁县| 天津市| 当阳市| 台安县| 青川县| 保德县| 临澧县| 凉山| 肥城市| 泾川县| 高青县| 崇明县| 温泉县| 襄垣县| 三台县| 阿拉尔市| 陈巴尔虎旗| 昭苏县| 铜山县| 广丰县| 监利县| 东兴市| 北海市|