JVM对字符串拼接的优化

发布于:2024-12-18 ⋅ 阅读:(49) ⋅ 点赞:(0)

不带变量的字符串拼接

    public static void main(String[] args) {

        String d = "hello" + "world";

    }
   L0
    LINENUMBER 7 L0
    LDC "helloworld"
    ASTORE 1
   L1

可以看出JVM就直接把计算好的字符串结果执行LDC操作。

带变量的字符串拼接(不是全部final变量)

    public static void main(String[] args) {

        String d = "hello" + "world";
        d = "hello" + "world" + d;

    }
    LINENUMBER 8 L1
    NEW java/lang/StringBuilder
    DUP
    INVOKESPECIAL java/lang/StringBuilder.<init> ()V
    LDC "helloworld"
    INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
    ALOAD 1
    INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
    INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;
    ASTORE 1

遇到变量,JVM会初始化一个StringBuilder实例去完成字符串的拼接工作。跟自己像下面代码直接初始化一个StringBuilder实例进行拼接操作是一样的。

d = new StringBuilder().append("hello" + "world").append(d).toString();

全部final变量字符串拼接

    public static void main(String[] args) {
        final String str1 = "hello";
        final String str2 = "world";
        String str3 = str1 + str2;
    }
   L0
    LINENUMBER 6 L0
    LDC "hello"
    ASTORE 1
   L1
    LINENUMBER 7 L1
    LDC "world"
    ASTORE 2
   L2
    LINENUMBER 8 L2
    LDC "helloworld"
    ASTORE 3

可以看到如果拼接的所有变量都是final变量,这里的操作类似不带变量的字符串拼接。由于中途为每一个子字符串产生了一个final变量,会相较于不带变量的字符串拼接多了LDC把变量数据从常量池入栈的操作,全部子字符串执行完LDC操作后,才会对拼接结果执行LDC操作。

如果拼接的子字符串并不是全部都是final变量,那么这样的操作就会回归到带变量的字符串拼接(不是全部final变量)操作。

	public static void main(String[] args) {
			final String str1 = "hello";
			String str2 = "world";
			String str3 = str1 + str2;
	}
	L0
		LINENUMBER 6 L0
		LDC "hello"
		ASTORE 1
	L1
		LINENUMBER 7 L1
		LDC "world"
		ASTORE 2
	L2
		LINENUMBER 8 L2
		NEW java/lang/StringBuilder
		DUP
		INVOKESPECIAL java/lang/StringBuilder.<init> ()V
		LDC "hello"
		INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
		ALOAD 2
		INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
		INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;
		ASTORE 3

能够看到,一样是初始化了一个StringBuilder实例,并使用这个StringBuilder实例进行了字符串拼接操作。


网站公告

今日签到

点亮在社区的每一天
去签到