ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

String类中 + 的奥秘

2019-08-25 20:04:28  阅读:307  来源: 互联网

标签:lang Ljava java String StringBuilder 奥秘 Method 类中


首先需要知道的是什么是字符串常量和字符串变量:

字符串常量:如”abc”

字符串变量:如String str1=”abc”  或者 String str2=new String(“abc”)

两种实例化方式,其中

String str1=”abc”  采用的是直接赋值的方式

String str2=new String(“abc”)  采用的是构造方法的方式


由于在JVM底层实际上会自动维护一个对象池(字符串对象池),如果现在采用了直接赋值的模式进行String类的对象实例化操作,那么该实例化对象(字符串内容)将自动保存到这个对象池之中。如果下次继续使用直接赋值的模式声明String类对象,此时对象池之中如若有指定内容,将直接进行引用;如若没有,则开辟新的字符串对象而后将其保存在对象池之中以供下次使用。但是如果采用的是构造方法的方式进行String类的对象实例化操作,那么此时会开辟两块堆空间,其中存放字符串常量的那块空间将成为垃圾空间,并且此时产生的实例化对象不会保存到对象池中。

String类中的==与equals:

==比较的是字符串地址值的内容;equals比较的是字符串的内容【覆写了Object类的equals方法】

下面看一段代码:

public class StringTest {
    public static void main(String[] args) {
        String str1 = "abc";
        String str2 = new String("abc");
        String str3 = "ab";
        String str4 = "c";
        String str5 = str3 + str4;
        String str6 = str3 + str4;
        String str7 = str3 + "c";  //这里的str3是变量
        String str8 = "ab" + "c";  //这里的"ab"、"c"是字符串常量 "ab"+"c"="abc"
        System.out.println(str1 == str2);  //false  只要出现了new,就一定开辟了新空间
        System.out.println(str1 == str5);  //false
        System.out.println(str1 == str6);  //false
        System.out.println(str5 == str6);  //false
        System.out.println(str5 == (str3 + str4));  //false
        System.out.println(str1 == str7);  //false
        System.out.println(str1 == str8); //true
    }
}

通过反编译我们来了解一下部分字节码:

//public static void main(java.lang.String[]);
//    descriptor: ([Ljava/lang/String;)V
//    flags: ACC_PUBLIC, ACC_STATIC
//    Code:
//      stack=4, locals=9, args_size=1
//         0: ldc           #2                  // String abc    str1
//         2: astore_1
//         3: new           #3                  // class java/lang/String   new:产生一个String对象
//         6: dup
//         7: ldc           #2                  // String abc
//         9: invokespecial #4                  // Method java/lang/String."<init>":(Ljava/lang/String;)V  str2
//        12: astore_2
//        13: ldc           #5                  // String ab   str3
//        15: astore_3
//        16: ldc           #6                  // String c    str4
//        18: astore        4
//        20: new           #7                  // class java/lang/StringBuilder  new:产生一个StringBuilder对象
//        23: dup
//        24: invokespecial #8                  // Method java/lang/StringBuilder."<init>":()V
//        27: aload_3
//        28: invokevirtual #9                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;  往StringBuilder对象中添加元素"ab"
//        31: aload         4
//        33: invokevirtual #9                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;  往StringBuilder对象中添加元素"c"
//        36: invokevirtual #10                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;    调用StringBuilder对象的toString方法返回一个String对象  str5
//        39: astore        5
//        41: new           #7                  // class java/lang/StringBuilder  new:产生一个StringBuilder对象
//        44: dup
//        45: invokespecial #8                  // Method java/lang/StringBuilder."<init>":()V
//        48: aload_3
//        49: invokevirtual #9                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;   往StringBuilder对象中添加元素"ab"
//        52: aload         4
//        54: invokevirtual #9                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;   往StringBuilder对象中添加元素"c"
//        57: invokevirtual #10                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;   调用StringBuilder对象的toString方法返回一个String对象  str6
//        60: astore        6
//        62: new           #7                  // class java/lang/StringBuilder   new:产生一个StringBuilder对象
//        65: dup
//        66: invokespecial #8                  // Method java/lang/StringBuilder."<init>":()V
//        69: aload_3
//        70: invokevirtual #9                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;  往StringBuilder对象中添加元素"ab"
//        73: ldc           #6                  // String c
//        75: invokevirtual #9                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;  往StringBuilder对象中添加元素"c"
//        78: invokevirtual #10                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;  调用StringBuilder对象的toString方法返回一个String对象  str7
//        81: astore        7
//        83: ldc           #2                  // String abc   str8
//        85: astore        8
//        87: getstatic     #11                 // Field java/lang/System.out:Ljava/io/PrintStream;
//        90: aload_1
//        91: aload_2
//        92: if_acmpne     99
//        95: iconst_1
//        96: goto          100
//        99: iconst_0
//       100: invokevirtual #12                 // Method java/io/PrintStream.println:(Z)V
//       103: getstatic     #11                 // Field java/lang/System.out:Ljava/io/PrintStream;
//       106: aload_1
//       107: aload         5
//       109: if_acmpne     116
//       112: iconst_1
//       113: goto          117
//       116: iconst_0
//       117: invokevirtual #12                 // Method java/io/PrintStream.println:(Z)V
//       120: getstatic     #11                 // Field java/lang/System.out:Ljava/io/PrintStream;
//       123: aload_1
//       124: aload         6
//       126: if_acmpne     133
//       129: iconst_1
//       130: goto          134
//       133: iconst_0
//       134: invokevirtual #12                 // Method java/io/PrintStream.println:(Z)V
//       137: getstatic     #11                 // Field java/lang/System.out:Ljava/io/PrintStream;
//       140: aload         5
//       142: aload         6
//       144: if_acmpne     151
//       147: iconst_1
//       148: goto          152
//       151: iconst_0
//       152: invokevirtual #12                 // Method java/io/PrintStream.println:(Z)V
//       155: getstatic     #11                 // Field java/lang/System.out:Ljava/io/PrintStream;
//       158: aload         5
//       160: new           #7                  // class java/lang/StringBuilder
//       163: dup
//       164: invokespecial #8                  // Method java/lang/StringBuilder."<init>":()V
//       167: aload_3
//       168: invokevirtual #9                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
//       171: aload         4
//       173: invokevirtual #9                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
//       176: invokevirtual #10                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
//       179: if_acmpne     186
//       182: iconst_1
//       183: goto          187
//       186: iconst_0
//       187: invokevirtual #12                 // Method java/io/PrintStream.println:(Z)V
//       190: getstatic     #11                 // Field java/lang/System.out:Ljava/io/PrintStream;
//       193: aload_1
//       194: aload         7
//       196: if_acmpne     203
//       199: iconst_1
//       200: goto          204
//       203: iconst_0
//       204: invokevirtual #12                 // Method java/io/PrintStream.println:(Z)V
//       207: getstatic     #11                 // Field java/lang/System.out:Ljava/io/PrintStream;
//       210: aload_1
//       211: aload         8
//       213: if_acmpne     220
//       216: iconst_1
//       217: goto          221
//       220: iconst_0
//       221: invokevirtual #12                 // Method java/io/PrintStream.println:(Z)V
//       224: return

总结:

1. 在String类中,只要有字符串变量的”+”,编译器都会将其优化为StringBuilder,而后调用append方法进行字符串的拼接,然后调用toString方法转为String(toString方法内部使用new String 返回String类的实例化对象)

所以在进行字符串变量相加后所得的字符串一定是一个新的字符串(因为开辟了新空间)  

注:一个字符串常量和一个字符串变量相加时也是要开辟新空间

2. 字符串常量相加后进行比较时,看的是常量池中是否有此相加的字符串,如果有则==为true

标签:lang,Ljava,java,String,StringBuilder,奥秘,Method,类中
来源: https://blog.csdn.net/ty6693/article/details/100066786

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有