美文网首页
Java 字符串初始化

Java 字符串初始化

作者: yangbug | 来源:发表于2019-02-14 10:19 被阅读0次

    今天小伙伴和我分享一个有意思的一段代码

    public static void main(string [] args){
            String str1 = "ABC";
            String str2 = "ABC";
            final String Str3 = "AB";
            String str4 = Str3 + "C";
            System.out.println(str1==str2);//true
            System.out.println(str2==str4);//true
    }
    

    final修饰Str3 是常亮时,str2 == str4

    public static void main(string [] args){
            String str1 = "ABC";
            String str2 = "ABC";
            String Str3 = "AB";
            String str4 = Str3 + "C";
            System.out.println(str1==str2);//true
            System.out.println(str2==str4);//false
    }
    

    Str3为普通变量时,str2 != str4。So Why?
    再看一下编译后的class文件

    //Str3 为 fianl 可以看到常量池中只有 ABC,AB因为没有用到所以编译器优化了
    Constant pool:
       #1 = Methodref          #6.#19         //  java/lang/Object."<init>":()V
       #2 = String             #20            //  ABC 常量池中只有ABC
       #3 = Fieldref           #21.#22        //  java/lang/System.out:Ljava/io/PrintStream;
       #4 = Methodref          #23.#24        //  java/io/PrintStream.println:(Z)V
       #5 = Class              #25            //  A
       #6 = Class              #26            //  java/lang/Object
       #7 = Utf8               <init>
       #8 = Utf8               ()V
       #9 = Utf8               Code
      #10 = Utf8               LineNumberTable
      #11 = Utf8               main
      #12 = Utf8               ([Ljava/lang/String;)V
      #13 = Utf8               StackMapTable
      #14 = Class              #27            //  "[Ljava/lang/String;"
      #15 = Class              #28            //  java/lang/String
      #16 = Class              #29            //  java/io/PrintStream
      #17 = Utf8               SourceFile
      #18 = Utf8               A.java
      #19 = NameAndType        #7:#8          //  "<init>":()V
      #20 = Utf8               ABC
      #21 = Class              #30            //  java/lang/System
      #22 = NameAndType        #31:#32        //  out:Ljava/io/PrintStream;
      #23 = Class              #29            //  java/io/PrintStream
      #24 = NameAndType        #33:#34        //  println:(Z)V
      #25 = Utf8               A
      #26 = Utf8               java/lang/Object
      #27 = Utf8               [Ljava/lang/String;
      #28 = Utf8               java/lang/String
      #29 = Utf8               java/io/PrintStream
      #30 = Utf8               java/lang/System
      #31 = Utf8               out
      #32 = Utf8               Ljava/io/PrintStream;
      #33 = Utf8               println
      #34 = Utf8               (Z)V
    
    //Str3 为 普通变量 ,可以看到常量池中有 ABC AB 以及 C
    Constant pool:
       #1 = Methodref          #12.#25        //  java/lang/Object."<init>":()V
       #2 = String             #26            //  ABC 
       #3 = String             #27            //  AB
       #4 = Class              #28            //  java/lang/StringBuilder
       #5 = Methodref          #4.#25         //  java/lang/StringBuilder."<init>":()V
       #6 = Methodref          #4.#29         //  java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
       #7 = String             #30            //  C
       #8 = Methodref          #4.#31         //  java/lang/StringBuilder.toString:()Ljava/lang/String;
       #9 = Fieldref           #32.#33        //  java/lang/System.out:Ljava/io/PrintStream;
      #10 = Methodref          #34.#35        //  java/io/PrintStream.println:(Z)V
      #11 = Class              #36            //  A
      #12 = Class              #37            //  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              #38            //  "[Ljava/lang/String;"
      #21 = Class              #39            //  java/lang/String
      #22 = Class              #40            //  java/io/PrintStream
      #23 = Utf8               SourceFile
      #24 = Utf8               A.java
      #25 = NameAndType        #13:#14        //  "<init>":()V
      #26 = Utf8               ABC
      #27 = Utf8               AB
      #28 = Utf8               java/lang/StringBuilder
      #29 = NameAndType        #41:#42        //  append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      #30 = Utf8               C
      #31 = NameAndType        #43:#44        //  toString:()Ljava/lang/String;
      #32 = Class              #45            //  java/lang/System
      #33 = NameAndType        #46:#47        //  out:Ljava/io/PrintStream;
      #34 = Class              #40            //  java/io/PrintStream
      #35 = NameAndType        #48:#49        //  println:(Z)V
      #36 = Utf8               A
      #37 = Utf8               java/lang/Object
      #38 = Utf8               [Ljava/lang/String;
      #39 = Utf8               java/lang/String
      #40 = Utf8               java/io/PrintStream
      #41 = Utf8               append
      #42 = Utf8               (Ljava/lang/String;)Ljava/lang/StringBuilder;
      #43 = Utf8               toString
      #44 = Utf8               ()Ljava/lang/String;
      #45 = Utf8               java/lang/System
      #46 = Utf8               out
      #47 = Utf8               Ljava/io/PrintStream;
      #48 = Utf8               println
      #49 = Utf8               (Z)V
    
    String str4 = Str3 + "天";
    

    首先 编译器理解C 是一个常亮,当Str3是变量时,编译器理解str4就是一个 变量 + 常量=变量,只能在运行时赋值。当Str3是常量时,编译器理解str4就是一个 常量 + 常量=常量,所以str4在处理化过程中就会预处理,在常量池中查找,并且赋值。

    相关文章

      网友评论

          本文标题:Java 字符串初始化

          本文链接:https://www.haomeiwen.com/subject/avedeqtx.html