文章目录
1.String,StringBuilder,StringBuffer的理解
1.String
String是被 final 修饰的,因此String是不可以被继承以及改变的,每次对String的改变,都会返回一个新的对象
String的底层是用数组实现的
private final char value[];
String s1 = "hello";
String s2 = new String("hello");
String s3 = "hello";
String s4 = new String("hello");
System.out.println(s1 == s2);
System.out.println(s1 == s3);
System.out.println(s2 == s4);
上述代码的执行结果:
false
true
false
s1和s3在创建的时候会现在常量池里面找有没有 “hello” 这个字符,如果有的话,会直接指向这个位置,如果没有的话,会在常量池中创建一块内存空间来存储 “hello” 这个字符,当创建s1的时候,常量池中是没有"hello"这个字符串的,所以它会开辟一块空间来存储"hello" ,而当s3执行的时候,常量池中是有"hello"这个字符的,所以它会直接指向这个"hello",所以s1和s3是相等的
而通过 new String() 的方式来创建对象时,它每次都会在堆上开辟一个新的空间来存储字符串,因此它们之间是不相等的
String s1 = "";
for (int i = 0;i < 1000; i++) {
s1 += "a";
}
上述的代码在执行的时候JVM会优化拼接方式,每加一次,JVM都会通过创建一个StringBuilder对象,并调用append()方法来实现拼接,如下图。
这样的话会造成一个问题,每一次拼接都会在堆上开辟一片空间,生成一个StringBuilder对象,这样会消耗内存资源

2.StringBuilder与StringBuffer
StringBuilder与StringBuffer差不多,不过最大的区别就是StringBuffer是线程安全的,而StringBuilder是线程不安全的,因为StringBuffer在许多方法面前都加了synchronized关键字修饰,因此
StringBuilder :效率高但线程不安全
StringBuffer :效率低但线程安全
StringBuilder和StringBuffer的底层也是使用数组实现的
StringBuilder builder = new StringBuilder();
for (int i = 0;i < 1000; i++) {
builder += "a";
}
这样的话,就不用每次都创建一个StringBuilder对象
2.String,StringBuilder,StringBuffer的比较
总结:
1、String一创建就不能修改,适合用在字符串不需要经常修改的场景
2、StringBuilder和StringBuffer差不多,只是StringBuffer是线程安全的,但是效率偏低,适合用在多线程环境下
3、StringBuilder速度快,线程不安全,适合用在单线程环境下
3.一些小问题
1、以下代码的执行结果是什么?
String a = "helloa";
String b = "hello" + "a":
System.out.println(a == b);
执行结果:
true
因为如果是想上述的直接拼接的方式,在编译的时候就会优化为"hello",所以a和b指向的其实是同一块常量池地址
2、以下代码的执行结果是什么?
String a = "helloa";
String b = "hello":
String c = b + "a":
System.out.println(a == c);
执行结果:
false
如果采用上述的引用拼接的话,在编译时不会优化,所以其实c是在堆内存中新开辟了一片空间,所以它们的引用地址不同,也就是false
3、以下代码的执行结果是什么?
String a = "helloa";
final String b = "hello":
String c = b + "a":
System.out.println(a == c);
执行结果:
true
beifinal修饰的值,在编译期间就会被代替为真正的值,例如上述代码的b其实在编译期间会直接替换为"hello",所以结果为true
4、以下代码在执行过多时候创建了几个对象
String str = new String("hello");
答案是1个,因为在编译的时候会在常量池中创建一个"hello"的对象,在执行的时候会在堆内存中创建一个"hello"对象,虽然总共创建了两个对象,但是在执行的时候就只创建了1个
5、以下代码的执行结果是什么?
public static String hello() {
return "hello";
}
String a = "helloa";
final String b = hello():
String c = b + "a":
System.out.println(a == c);
执行结果:
false
上一题虽然说过b被final修饰,所以在编译的时候会被代替为实际的值,但是当它调用方法的时候,其实是不一样的,因为当它调用方法时,在编译的时候,并不能确定b的值,所以只有在运行的时候它才能确定b的值,所以是false
本文深入探讨了Java中的String、StringBuilder和StringBuffer的区别与应用场景,详细解释了它们的内部实现原理及性能特点。
942

被折叠的 条评论
为什么被折叠?



