Java字符串对象的创建与拼接

javaString是Java中最常用的类之一。

对于String,Java Doc中描述是一旦被创建就不能被更改(“Strings are constant; their values cannot be changed after they are created”),任何对String对象的修改操作都会生成新的String对象。

了解String对象创建与拼接的一些内部细节,有利于更高效地对字符串进行操作。

String对象的创建

String对象有两种创建形式:

  1. 编译期能确定的字符串对象,会放到Java内存空间的常量池中,编译器首先检查常量池,是否已存在该字符串,若不存在,则先创建并指向,若存在则直接将引用指向那个字符串(对于内容相同的字符串仅保留一份)。
  2. 使用new关键词创建字符串对象,在堆上分配,运行期创建,与其他对象一样,即使内容相同也是不同的对象。

如下代码:

使用javap反编译为字节码:

可以看到:

  • 对于 s1 = "abc",s1指向常量池中的字符串”abc”;
  • 对于 s2 = "ab" + "c",编译器进行了优化,s2同样指向了常量池中的字符串”abc”;
  • 对于 s3 = new String("abc"),编译器使用new指令创建堆上的对象;
  • 对于 s4 = "ab"; s4 += "c";,编译器首先将s4指向常量池中的对象”ab”,然后构建的StringBuilder对象拼接了”c”,返回的是堆上的对象。

那么:

  • 对于 s1 == s2,值为 true
  • 对于 s1 == s3,值为 false
  • 对于 s1 == s4,值为 false
  • 对于 s3 == s4,值为 false

String对象的拼接

如下代码:

使用javap反编译为字节码:

可以看到:

  • 对于 s1 = "ab" + "c",编译器优化为”abc”直接放入常量池;
  • 对于 s2 = "a"; s2 += "b"; s2 += "c";,每一个+=操作,都创建了一个新的StringBuilder对象;
  • 对于 s3 = "a"; s3 = s3 + "b"; s3 = s3 + "c";,同s2;
  • 对于 s4 = new StringBuffer().append("a").append("b").append("c").toString();,很明显只有一个StringBuilder对象。

所以,对于连续的字符串变量拼接操作,尤其是循环中的,要在循环外创建StringBuilder对象用于循环内的拼接,若使用+=运算符,每次循环都会创建新的StringBuilder对象,大大降低效率。

参考链接

http://docs.oracle.com/javase/7/docs/api/java/lang/String.html

http://www.cnblogs.com/hzmark/archive/2012/12/10/JavaString.html

发表评论

电子邮件地址不会被公开。 必填项已用*标注