字符串连接原理

发布时间 2023-09-09 11:54:27作者: SimpleWord
title: 字符串连接原理
index_img: img/2.svg
tags:
  - Java SE
  - 字符串
categories:
  - Java SE
hide: false
excerpt: 字符串拼接方式、效率、对象

使用+运算符

无变量参与

  • 运行前就直接拼接为一个字符串
public class Main {
    public static void main(String[] args) {
        String s = "Hello " + "World"+"!";
    }
}

在编译后实际上会变成:

public class Main {
    public Main() {
    }

    public static void main(String[] var0) {
        String var1 = "Hello World!";
    }
}

jdk8之前(有变量参与)

public class Main {
    public static void main(String[] args) {
        String s1 = "Hello";
        String s2 =s1+"world";
        String s3 =s2+"!";
    }
}

每次+堆中都会创建StringBuilderString对象,字符串常量池中会添加HelloWorld!,效率低且浪费空间。(StringBuilder高效率是针对一个StringBuilder而言)

//等效代码
public class Main {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        String s1 = "Hello";
        sb.append(s1);
        String s2 = sb.append("world").toString();
        String s3 = sb.append("!").toString();
    }
}

jdk8之后(有变量参与)

public class Main {
    public static void main(String[] args) {
        String s1 = "a";
        String s2 = "b";
        String s3 = "c";
        String s4 = s1 + s2 + s3;
    }
}
  • jdk8之前堆中会产生4个对象,字符串常量池中会有3个对象

  • jdk8之后堆中会产生1个对象,字符串常量池中会有3个对象

jdk8之后,每+都会产生新的预估数组和一个String对象,依旧效率低。

注意

先判断是否有变量参与,再判断是否分析常量池(会复用)和堆。

StringBuilder

StringBuilderStringBuffer 是专门用于处理字符串连接的类。StringBuffer 是线程安全的,而 StringBuilder 不是,因此在不涉及多线程的情况下,一般推荐使用 StringBuilder

public class Main {
    public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("a");
        stringBuilder.append("b");
        stringBuilder.append("c");
        System.out.println(stringBuilder); // 还是StringBuilder对象
    }
}

StringBuilder可变的。只会产生一个。

StringBuilder (或 StringBuffer) 内部使用一个 char[] 数组来存储字符串。当数组容量不足以容纳新的字符时(StringBuilder默认16字节),它会创建一个新的数组,大小是旧数组的2倍+2,然后将旧数组的内容复制到新数组中。