您的位置:首页 > 产品设计 > UI/UE

JAVA基础:String, StringBuffer, StringBuilder ——区别,用法及常见问题

2016-09-04 11:41 1141 查看

引言

这几天看到知乎上讨论一道入门级JAVA面试题目,发现自己竟然答不上来,遂查阅相关资料恶补一下。

问题:String,StringBuffer和StringBuilder区别?

衍生问题

- 为什么能节省内存?

- string设计为不可变(immutable)的意义是什么?

- JVM回收的速度慢到需要特别重视这个问题吗?

- 常量池?GC?JVM优化

- 什么是线程(线程安全&非线程安全)?

- 如何实现线程安全?有几种方式实现线程安全?

- 线程同步?

- JRE中常用的String开头的class有哪些?

Overview

-StringStringBufferStringBuilder
可变性No(不可变)Yes(可变)Yes(可变)
线程安全YesYesNo
简述:JAVA中的String类型是immutable不可变的(被final修饰),因此当修改String的值时,并不是在String原来的空间上修改,而是重新开辟了一段空间存储新的String。这样一来,当需要大量的对String的值进行修改时,每次修改都会生成一个新的常量(放入常量池),特别是当内存中无引用的对象多了以后,JVM的GC就开始工作,性能随之降低。

而使用StringBuffer类时,每次修改都是在原有的数据上操作,而不是生成新的对象。StringBuilder是StringBuffer的简化版本,StringBuffer是线程安全的,而StringBuilder没有考虑线程安全。

因此就可得出它们的使用场景:

- String:字符串相加操作少、改动少,使用String;

- StringBuffer:字符串操作较多,涉及多线程;

- StringBuilder :字符串操作较多,不涉及多线程。

常见问题

1 下面代码的输出结果是什么?

String a = "HelloWorld";
String b = "Hello" + "World";
System.out.println((a==b));


结果:true

“Hello” + “World”在编译期间就被优化为”HelloWorld”,因此运行时a与b指向的是同一个对象。

2 下面代码的输出结果是什么?

String a = "HelloWorld";
String b = "Hello";
String c = b + "World";
System.out.println((a==c));


结果:false

由于有符号引用,b + “World”不会在编译期间被优化,因此c也就不会被当作常量处理,a和c不是指向的同一个对象。

3 下面代码的输出结果是什么?

String a = "HelloWorld";
final String b = "Hello";
String c = b + "World";
System.out.println((a==c));


结果:true

对于final修饰的变量,会在class文件常量池中保存一个副本,对final变量的访问在编译期间都会直接被替代为真实的值,那么String c = b+ “World”在编译期间就会被优化为String c = “Hello” + “World”。

但是,如果final String b = getHello();

public static String getHello(){
return "Hello";
}


那么结果就是false,因为虽然b被final修饰,但是b的值是通过方法返回的,只能在运行期间确定,因此a与c指向的就不是同一个对象。

4 String str = new String(“abc”)创建了多少个对象?

并不能单纯的说创建了1个或者两个对象,因为这行代码的确在运行期间只创建了一个对象,但是在类加载过程中,在运行时常量池创建了一个”abc”对象,而在代码运行过程中确实只创建了一个String对象。

如果换成,这行代码涉及几个对象,那就是2个;而执行过程中,是创建了一个。

5 下面这段代码,(1)和(2)的区别是什么?

public class Main{
public static void main(String[] args){
String str = "How";
str += "are" + "you";       // (1)
str = str + "are" + "you";  // (2)
}
}


(1)的效率要比(2)高,因为(1)中的”are” + “you”在编译期间会被优化为”areyou”,而(2)不会被优化。

Reference

http://www.cnblogs.com/dolphin0520/p/3778589.html

http://blog.csdn.net/kingzone_2008/article/details/9220691

http://www.iteye.com/topic/774673
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  JAVA jvm
相关文章推荐