String 拼接值的比较

参考下面代码和说明:

	@Test
    public void test() {
        /**
         * String str1= “abc”; 在编译期,JVM会去常量池来查找是否存在“abc”,
         * 如果不存在,就在常量池中开辟一个空间来存储“abc”;
         * 如果存在,就不用新开辟空间。然后在栈内存中开辟一个名字为str1的空间,来存储“abc”在常量池中的地址值。
         *
         * String str2 = new String("abc") ;
         * 在编译阶段JVM先去常量池中查找是否存在“abc”,
         * 如果过不存在,则在常量池中开辟一个空间存储“abc”。
         * 在运行时期,通过String类的构造器在堆内存中new了一个空间,
         * 然后将String池中的“abc”复制一份存放到该堆空间中,
         * 在栈中开辟名字为str2的空间,存放堆中new出来的这个String对象的地址值。
         * 不论new String这种方式在常量池是否创建对象,它指向的始终是堆中的对象。
         * 堆中对象指向字符串常量池中的”abc“/或者说堆中对象又存有字符串常量池中"abc"的引用地址
         */
        String s1 = "Programming";
        String s2 = new String("Programming");
        String s3 = "Program";
        String s4 = "ming";
        /**
         * 常量加常量
         * 编译器自动优化成 "Programming";
         */
        String s5 = "Program" + "ming";
        /**
         * 变量加变量==变量加常量
         * 变量加常量会new一个Stringbuilder并且调用Stringbuilder.appen方法将他们拼接在一起
         * String s6 = s3 + s4;
         * 等价于String s6 = s3 + "ming";String s6 = "Program" + s4;
         * 等价于
         * StringBuilder s = new StringBuilder();
         * s.append("Program");
         * s.append("ming");
         * String str = stringB.toString();
         * StringBuilder.toString 等价于 new String() 括号里是StringBuilder的值"Programming"
         */
        String s6 = s3 + s4;

        StringBuilder s7 = new StringBuilder();
        s7.append(s3);
        s7.append(s4);
        String s8 = s7.toString();
        System.out.println(s6 == s8);//false

        /**
         * 通过字面量赋值创建字符串(如:String s=”string”)时,会先在常量池中查找是否存在相同的字符串,
         * 若存在,则将栈中的引用直接指向该字符串;
         * 若不存在,则在常量池中生成一个字符串,再将栈中的引用指向该字符串。
         *
         */
        System.out.println(s1 == s2);//false
        System.out.println(s1 == s5);//true
        System.out.println(s1 == s6);//false
        System.out.println(s1 == s6.intern());//true
        /**
         * s2在堆中
         * s2.intern()在字符串常量池中
         * new String()都是在堆上创建字符串对象。当调用 intern() 方法时,编译器会将字符串添加到常量池中并返回指向该常量的引用。
         */
        System.out.println(s2 == s2.intern());//false

        /**
         * String s12 = s9 + s10;等价于 "a"+"b"
         * 编译期优化后 直接赋值给s12 = "ab"
         *
         * 字符串拼接操作不一定使用的是stringBuilder!
         * 如果拼接符号左右两边都是字符串常量或常量引用,则仍然使用编译期优化,即非stringBuilder的方式。
         *
         * 针对于final修饰类、方法、基本数据类型、引用数据类型的量的结构时,能使用上final的时候建议使用上。
         * 在linking准备阶段就对静态变量进行默认值初始化,如果是有final修饰的就显示初始化了
         */
        final String s9 = "a";
        final String s10 = "b";
        String s11 = "ab";
        String s12 = s9 + s10;
        String s13 = s9 + "b";
        System.out.println(s11 == s12);//true
        System.out.println(s11 == s13);//true
    }

String.intern()是一个Native方法,底层调用C++的 StringTable::intern方法实现。当通过语句str.intern()调用intern()方法后,JVM 就会在当前类的常量池中查找是否存在与str等值的String,若存在则直接返回常量池中相应Strnig的引用;若不存在,则会在常量池中创建一个等值的String,然后返回这个String在常量池中的引用。因此,只要是等值的String对象,使用intern()方法返回的都是常量池中同一个String引用,所以,这些等值的String对象通过intern()后使用==是可以匹配的。

变量加变量==变量加常量 字节码指令说明图
在这里插入图片描述
注意
字符串拼接操作不一定使用的是StringBuilder
如果拼接符号左右两边都是字符串常量或常量引用,则仍然使用编译期优化,即非StringBuilder的方式。
针对于final修饰类、方法、基本数据类型、引用数据类型的量的结构时,能使用上final的时候建议使用上。在linking准备阶段就对静态变量进行默认值初始化,如果有final就显示初始化了。如上述代码中s12的示例

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C++中,可以使用+运算符或append()函数来拼接字符串。引用中的代码中展示了一些字符串拼接的示例。 使用+运算符: string str1 = "ls"; string str2 = "test.c"; string str3 = str1 + " /tmp/"; // str3的为"ls /tmp/" string str5 = str1 + " append " + "haha"; // str5的为"ls append haha" 使用append()函数: string tmp = str1 + " append"; string str5 = tmp.append("haha"); // str5的为"ls append haha" 另外,引用提到了使用push_back()函数来拼接字符串,这是一种高效的方式。 所以,在C++中,可以使用+运算符、append()函数或push_back()函数来进行字符串拼接。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [C++ String拼接](https://blog.csdn.net/u013105549/article/details/52854368)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *3* [C++ string类型字符串拼接](https://blog.csdn.net/neuzhangno/article/details/128686544)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值