• 解析字符串拼接的两种情况


    解析字符串拼接的两种情况

    1 字符串字面量进行拼接

    1.1 内容

    1.1.1 例子

    如String s1=“s”+“h”;String s2=“sh”;

    1.1.2 分析过程

    s1=“s”+"h"这个过程

    a 在字符串常量池中先查看是否有已经开辟了s字符串和h字符串的空间
    b 若没有则需要先在字符串常量池里面开辟字符串字面量s和字符串字面量h的空间
    c 因为使用了+进行拼接,所以也会先去字符串常量池中查找里面是否已经存在sh这个字面量了,
    d 我们这个时候发现里面并没有存在sh这个字符串,因此会去开辟一个属于sh字符串的空间,并把这个空间的地址赋值给了s1

    s2="sh"这个过程

    我们会先去字符串常量池中查找是否已经存在sh这个字符串,发现已经存在了这个字符串,那么我们这个时候只需要将"sh"这个字符串在字符串常量池中的内存地址赋值给s2就行

    结论: s1==s2的结果为true

    因为s1、s2指向的内存地址都相同,都指向的是在字符串常量池中的"sh"这个字符串开辟的空间

    1.2 示例代码

    package Work;
    public class Test05 {
        public static void main(String[] args) {
           String s1="s"+"r";
           String s2="sr";
           System.out.println(s1==s2);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    1.3 示例代码生成的字节码文件的反编译代码

    package Work;
    
    import java.io.PrintStream;
    
    public class Test05
    {
    
    	public Test05()
    	{
    	}
    
    	public static void main(String args[])
    	{
    		String s1 = "sr";
    		String s2 = "sr";
    		System.out.println(s1 == s2);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    1.4 示例代码运行截图

    在这里插入图片描述

    2 字符串变量进行拼接

    2.1 内容

    a 如果是字符串变量进行拼接,这个时候就会new StringBuilder对象去进行拼接,
    b 因为它并不知道你那个变量里面存放了多长的字符串,用字符串常量池去存储变量的会没有必要,因此为了节约空间,因此只要涉及到字符串变量与字符串字面量(能清楚的知道里面的值,如"12")的拼接操作本质上还是new了一个StringBuilder去进行拼接操作(append),
    c 然后调用toString方法(本质还是new了一个String对象进行返回的)去返回String对象

    2.2 示例代码

    package Work;
    public class Test05 {
        public static void main(String[] args) {
           String s1="s";
           String s2=s1+"r";
           String s3="sr";
           System.out.println(s2==s3);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2.3 示例代码生成的字节码文件的反编译代码

    package Work;
    
    import java.io.PrintStream;
    
    public class Test05
    {
    
    	public Test05()
    	{
    	}
    
    	public static void main(String args[])
    	{
    		String s1 = "s";
    		String s2 = (new StringBuilder()).append(s1).append("r").toString();
    		String s3 = "sr";
    		System.out.println(s2 == s3);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    2.3 示例代码运行截图

    在这里插入图片描述

    3 总结

    3.1 只要涉及到字符串变量与字符串字面量进行拼接操作,那么它一定会new StringBuffer对象去进行拼接操作,然后调用StringBuffer对象里面的toString方法(实际上了new了一个String对象)去返回一个String类型的结果

    3.1.1 StringBuffer的toString方法源码

     public String toString() {
         // Create a copy, don't share the array
         return new String(value, 0, count);
    }
    
    • 1
    • 2
    • 3
    • 4

    3.2 如果是字符串字面量与字符串字面量进行拼接,那么还是去方法区的字符串常量池去开辟空间,进行==比较的话还是去看他们俩指向的字符串常量池的字符串的地址是否相同

  • 相关阅读:
    传智教育|Git实战-上线出bug,如何代码回滚?
    C语言:堆
    mysql远程连接失败
    《网络安全笔记》第十四章:交换机的工作原理
    (十二)Java算法:桶排序(详细图解)
    MySQL——读写分离
    Java通过反射模拟冰蝎免杀功能
    PHP+Redis+Lua 实现 Redis 分布式锁
    shiro原理及其运行流程介绍
    C#控制台程序中使用log4.net来输出日志
  • 原文地址:https://blog.csdn.net/SSS4362/article/details/126064835