字符串的内部存储原理

时间:2024-05-20 13:56:39

字符串的存储

字符串是一个字面量,它的值存储在常量池中(也就是方法区的运行时常量池),他的底层是使用字符数组来存储,它是可以共享的。以下展示直接字符串与字符串对象的存储。

字符串的内部存储原理

其中String s1 = “ab”;会产生一个对象,也就是它底层的字符数组。

单独的String s2 = new String(“ab”);是会产生两个对象的,也就是堆内存中new出来的对象,和字符数组。

如果两个同时创建则只会产生两个对象,也就是字符数组和堆内存中new出来的对象。至于方法区的常量池中的字面量和字符数组会共享。

字符串的拼接

public class StringDemo1 {
	
	public static void main(String[] args) {
		
		// String s1 = "abc";
		// s1 = "def";
		// 指向常量池
		String s1 = "ab";
		// 指向堆内存
		String s2 = new String("ab");
		// "a"和"b"是两个字面量
		// 两个字面量在运算的时候为了提高效率,在编译的时候会进行自动的计算优化
		// byte b = 3 + 5; -> byte b = 8;
		// String s3 = "ab";
		String s3 = "a" + "b";
		// 字符串在使用+拼接的时候底层实际上是调用了StringBuilder中的append方法
		String s4 = "a";
		// s4 = new StringBuilder(s4).append("b").toString();
		// s4 = new String("ab");
		s4 = s4 + "b";
		
		System.out.println(s1 == s2);
		System.out.println(s1 == s3);
		System.out.println(s1 == s4);
		System.out.println(s2 == s4);
		
	}

}

这里需要注意几个点:

①两个字面量在运算的时候为了提高效率,在编译的时候会进行自动的计算优化。也就是在写出String str = “a” + “b”; 和String str = “ab”;的编译完成时的效果是一样的。

②当以new的形式去创建一个字符串的时候,指针直接指向的地址是堆内存中的地址。

③当变量和常量进行相加的时候是不会再编译期自动运算的。而是创建一个StringBuilder然后在后面追加一个字符串,然后再new一个新的对向也就是它的toString方法。最后指向的是这个toString之后所new的对象。

这里就详细说明一下字串的拼接步骤如下:

String str = “a”;

String str1 = “b”;

str = str + str1;

①new StringBuilder(“a”); // 这时会产生一个新的对象

②.append(“b”);// append完成之后就又会产生一个对象

③.toString();// 这时会new一个String的对象。

前前后后涉及到了5个对象也就是拼接好一次需要多产生3个对象。

 

那么这个过程直接用StringBuilder的append呢?

也就是上述过程的②③步骤,会多产生2个对象。需要注意的是StringBuilder只是在最后一次toString一把而在使用+的时候每次连接都会toString一把。