java String常量池与字符串拼接性能优化
2017-06-23 19:54
501 查看
----String常量池----
1.常量池中的对象从哪里来的?
当我们创建String对象采用字面量形式时,JVM首先会对这个字面量进行检查,如果常量池中存放有该字面量,则直接使用,否则创建新的对象并将其引用放入常量池中。
当我们通过new来创建一个字符串时,JVM就不会去常量池中找,而是直接在堆中新建一个对象。如果我们想把new的对象也放在常量池中,可以调用方法inner();
当我们new新的对象时,之后再调用intern()方法,如果没有把s2重新引用则s2仍为原来的对象,此时s1不等于s2,若重新引用常量池中的对象,则s1等于s2
![](https://oscdn.geek-share.com/Uploads/Images/Content/201706/c58eb33fc0ea359ec4ef547a16ef23c9)
2.常量池中存的是对象还是引用?
常量池中存的是对对象的引用,存储于JVM的方法区中,而且引用的对象存储于堆中。
3.常量池中的对象会被GC回收吗?
当常量池中的引用没有被任何变量引用时,就会被GC回收!
![](https://oscdn.geek-share.com/Uploads/Images/Content/201706/e277625cde705ad93aabfe0a20297ee5)
----字符串拼接----
1.字符串拼接的内部实现
正常情况下,执行声明s1代码会生成3个对象,即对象a、对象ab、对象abc,其中对象a和对象ab都是中间的临时变量,最后的对象abc才赋值给了s1。因此在使用字符串拼接的时候,拼接的数量越多,性能越低!
但是java编译器在编译的时候做了优化,在编译时新建一个对象StringBuilder来拼接,这样就避免了产生很多临时对象,从而提升了性能!但是一下代码性能就低下:
之所以低下的原因是因为循环内,每次都在做字符串拼接,每次都在产生一个StringBuilder对象,造成内存的浪费!因此这种错误要尽量避免,稍做以下优化即可完美改造:
以上代码通过在循环为new一个StringBuilder对象来拼接,这样就避免了循环中创建对象了!
2.字符串拼接的性能优化
通过以上案例,我们就已经知道了字符串拼接时尽量使用StringBuilder或者StringBuffer对象,特别时循环中的拼接!
3.StringBuilder与StringBuffer的区别
两者的共同点都是建立一个字符串缓冲区,然后调用相关方法操作字符串!不同点就是StringBuilder是非同步的,而StringBuffer是同步的,因此StringBuilder执行效率更高,在不需要同步的情况下优先使用StringBuilder,否则使用StringBuffer来保证数据的同步,即多线程的情况下!
更多参考:
字符串常量池介绍
字符串拼接细节分析
interned Strings : Java Glossary
1.常量池中的对象从哪里来的?
String s1="hanhan"; String s2="hanhan"; System.out.println(s1==s2);//true
当我们创建String对象采用字面量形式时,JVM首先会对这个字面量进行检查,如果常量池中存放有该字面量,则直接使用,否则创建新的对象并将其引用放入常量池中。
String s1="han"; String s2=new String("han"); System.out.println(s1==s2);//false
当我们通过new来创建一个字符串时,JVM就不会去常量池中找,而是直接在堆中新建一个对象。如果我们想把new的对象也放在常量池中,可以调用方法inner();
String s1="guoguo"; String s2=new String("guoguo").intern(); System.out.println(s1==s2);//true
当我们new新的对象时,之后再调用intern()方法,如果没有把s2重新引用则s2仍为原来的对象,此时s1不等于s2,若重新引用常量池中的对象,则s1等于s2
String s1="gh"; String s2=new String("gh"); s2.intern(); System.out.println(s1==s2);//false; s2=s2.intern(); System.out.println(s1==s2);//true;
2.常量池中存的是对象还是引用?
常量池中存的是对对象的引用,存储于JVM的方法区中,而且引用的对象存储于堆中。
3.常量池中的对象会被GC回收吗?
当常量池中的引用没有被任何变量引用时,就会被GC回收!
----字符串拼接----
1.字符串拼接的内部实现
String s1="a"+"b"+"c";
正常情况下,执行声明s1代码会生成3个对象,即对象a、对象ab、对象abc,其中对象a和对象ab都是中间的临时变量,最后的对象abc才赋值给了s1。因此在使用字符串拼接的时候,拼接的数量越多,性能越低!
但是java编译器在编译的时候做了优化,在编译时新建一个对象StringBuilder来拼接,这样就避免了产生很多临时对象,从而提升了性能!但是一下代码性能就低下:
String s=""; for(int i=0;i<length;i++){ s+=i; }
之所以低下的原因是因为循环内,每次都在做字符串拼接,每次都在产生一个StringBuilder对象,造成内存的浪费!因此这种错误要尽量避免,稍做以下优化即可完美改造:
String s=""; StringBuilder sb=new StringBuilder(); for(int i=0;i<length;i++){ sb.append(i); }
以上代码通过在循环为new一个StringBuilder对象来拼接,这样就避免了循环中创建对象了!
2.字符串拼接的性能优化
通过以上案例,我们就已经知道了字符串拼接时尽量使用StringBuilder或者StringBuffer对象,特别时循环中的拼接!
3.StringBuilder与StringBuffer的区别
两者的共同点都是建立一个字符串缓冲区,然后调用相关方法操作字符串!不同点就是StringBuilder是非同步的,而StringBuffer是同步的,因此StringBuilder执行效率更高,在不需要同步的情况下优先使用StringBuilder,否则使用StringBuffer来保证数据的同步,即多线程的情况下!
更多参考:
字符串常量池介绍
字符串拼接细节分析
interned Strings : Java Glossary
相关文章推荐
- java性能优化之String字符串优化
- Java jdk对String字符串拼接的优化
- Java优化编程--核心类与性能 Vector ArrayList LinkedList String
- 【转载】Java 性能优化之 String 篇
- Java 性能优化之 String 篇
- Java性能优化:字符串过滤
- Java 5种字符串拼接方式性能比较
- Java 5种字符串拼接方式性能比较。 .
- Java String字符串拼接,截取,查找及日期转换
- Java 性能优化之 String 篇
- Java 性能优化之 String 篇
- Java 5种字符串拼接方式性能比较
- Java从入门到精通 - JavaString 字符串拼接,截取,查找及日期转换
- Java 性能优化之 String 篇
- Java中字符串累加的性能优化
- String和StringBuffer——字符串性能优化总结
- JAVA的字符串拼接与性能
- java字符串拼接与性能
- JAVA的字符串拼接与性能