Java中的String、StringBuilder以及StringBuffer

来源:互联网 发布:网络天天分红投资公司 编辑:程序博客网 时间:2024/05/21 06:26

String是final类!

String str1 = “hello world”的意义–(方法区)

在编译期间生成了 字面常量和符号引用
运行期间字面常量”hello world”被存储在运行时常量池(方法区中)(当然只保存了一份)。
通过这种方式来将String对象跟引用绑定的话,JVM执行引擎会先在运行时常量池查找是否存在相同的字面常量
如果存在,则直接将引用指向已经存在的字面常量;
否则在运行时常量池开辟一个空间来存储该字面常量,并将引用指向该字面常量。

String str=new String(“hello world”)的意义–(堆中)

通过new关键字来生成对象是在区进行的,而在堆区进行对象生成的过程是不会去检测该对象是否已经存在的
因此通过new来创建对象,创建出的一定是不同的对象,即使字符串的内容是相同的。

String、StringBuilder、StringBuffer三者的执行效率:(相对而言,并不一定)

StringBuilder > StringBuffer(StringBuffer类的成员方法前面多了一个关键字:synchronized) > String

很有趣的问题

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

String a = “hello2”;  
String b = “hello” + 2;  
System.out.println((a == b));

  输出结果为:true。原因很简单,”hello”+2在编译期间就已经被优化成”hello2”,因此在运行期间,变量a和变量b指向的是同一个对象。

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

String a = “hello2”;
String b = “hello”;
String c = b + 2;
System.out.println((a == c));

 输出结果为:false。由于有符号引用的存在,所以 String c = b + 2;不会在编译期间被优化,不会把b+2当做字面常量来处理的,因此这种方式生成的对象事实上是保存在堆上的。因此a和c指向的并不是同一个对象

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

String a = “hello2”;
final String b = “hello”;
String c = b + 2;
System.out.println((a == c));

  输出结果为:true。对于被final修饰的变量,会在class文件常量池中保存一个副本,也就是说不会通过连接而进行访问,对final变量的访问在编译期间都会直接被替代为真实的值。那么String c = b + 2;在编译期间就会被优化成:String c = “hello” + 2;
  
4.String str = new String(“abc”)创建了多少个对象?

new只调用了一次,也就是说只创建了一个对象。

5.String str = new String(“abc”)涉及到几个String对象?

2个

总结

StringBuffer是线程安全的,所以效率上比Stringbuilder差一些

关于编译器自动优化的问题,如果在编译期间能确定值,编译器会进行优化,有符号引用存在的话就不能优化

new String()是对象,在堆中

直接赋值,其实是先在运行时常量池中寻找是否有相同的相同的字面常量,有就直接引用过去,没有的话先创建再引用。

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

0 0