String a = "123",String b = "123", b == a 是会返回true的,这里牵扯到了字符串常量池,因为很多字符串都是常见的,不可能每个字符串都创建一个对象吧?你有一个“abc”字符串,他也有一个,有10000个“abc”字符串就要创建10000个“abc”字符串?这样对性能和内存肯定有损耗,所以JVM中就会有一个字符串常量池(Java6中被缓存的字符串是存在所谓 PermGen 里的,也就是臭名昭著的的“永久代”,这个空间是有限的,也基本不会被FullGC之外的垃圾收集照顾到。所以使用不当,OOM就会光顾。在后续版本中,这个缓存被放置在堆中,这样就极大避免了永久代占满的问题,甚至永久代在JDK8中被MetaSpace(元数据区)替代了。而且默认缓存大小也在不断扩大中,从最初的1009,到7u40以后被修改为60013。)来保存字符串常量,以上定义的变量a,和b之所以用"=="相比较返回true是因为他们都指向同一个字符串对象。
当然以上情况要注意的是:String a = new String("123”) ,String b = new String("123”)这样的写法,a == b返回的就是false了。
计算中注意的两点,String a = "123" + "123 + "2341";这种写法,在编译期就已经确定了字符串“1231232341”,所以速度还是很快的。但是如果用下面这种字符串拼接方式,那么就会导致性能大减,这也是String拼接字符串效率最低的原因之一了吧。String a = "123",a += "23"; a += "cb";这种情况下,String底层会实例化一个一个有一个的StringBuilder对象并且利用append方法来拼接字符串。当字符串拼接量比较大的时候,可想而知创建那么多StringBuilder对象造成的性能开销和内存开销了。