Comparing strings with == which are declared final in Java

后端 未结 6 618
醉酒成梦
醉酒成梦 2020-11-22 14:46

I have a simple question about strings in Java. The following segment of simple code just concatenates two strings and then compares them with ==.



        
6条回答
  •  醉梦人生
    2020-11-22 15:28

    If you take a look at this methods

    public void noFinal() {
        String str1 = "str";
        String str2 = "ing";
        String concat = str1 + str2;
    
        System.out.println(concat == "string");
    }
    
    public void withFinal() {
        final String str1 = "str";
        final String str2 = "ing";
        String concat = str1 + str2;
    
        System.out.println(concat == "string");
    }
    

    and its decompiled with javap -c ClassWithTheseMethods versions you will see

      public void noFinal();
        Code:
           0: ldc           #15                 // String str
           2: astore_1      
           3: ldc           #17                 // String ing
           5: astore_2      
           6: new           #19                 // class java/lang/StringBuilder
           9: dup           
          10: aload_1       
          11: invokestatic  #21                 // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
          14: invokespecial #27                 // Method java/lang/StringBuilder."":(Ljava/lang/String;)V
          17: aload_2       
          18: invokevirtual #30                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          21: invokevirtual #34                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
          ...
    

    and

      public void withFinal();
        Code:
           0: ldc           #15                 // String str
           2: astore_1      
           3: ldc           #17                 // String ing
           5: astore_2      
           6: ldc           #44                 // String string
           8: astore_3      
           ...
    

    So if Strings are not final compiler will have to use StringBuilder to concatenate str1 and str2 so

    String concat=str1+str2;
    

    will be compiled to

    String concat = new StringBuilder(str1).append(str2).toString();
    

    which means that concat will be created at runtime so will not come from String pool.


    Also if Strings are final then compiler can assume that they will never change so instead of using StringBuilder it can safely concatenate its values so

    String concat = str1 + str2;
    

    can be changed to

    String concat = "str" + "ing";
    

    and concatenated into

    String concat = "string";
    

    which means that concate will become sting literal which will be interned in string pool and then compared with same string literal from that pool in if statement.

提交回复
热议问题