标签:描述 title uga any 修改 equals 也会 tle https
以下是从网上整理出的资料,不同作者对某些具体描述有略微差别,有的具体描述可能会存在不准确的情况,但结论是一致的。
equals比较值,==比较引用,我们主要关注引用的比较。
String s1="abc"; String s2="abc"; String s3 = new String("abc"); System.out.println(s1==s2); System.out.println(s1==s3); 输出结果: true false
对于 String s1="abc"; 这种方式,如果常量池中已经存在字符串“abc”,会直接引用这个字符串,否则会创建一个“abc”字符串,所以对于s1、s2来说,引用指向的地址是一样的,返回true。相当于s1,s2 —>常量池中的字符串。(有点不能确定的是,如果是基本类型的数据,是把常量池的地址拷贝到栈中,还是栈中的引用直接指向常量池,这里暂时认为是后者)
对于 String s3 = new String("abc"); 这种方式,无论如何都会在堆中new一个String("abc")对象,当然如果常量池中没有"abc"字符串,也会先创建。相当于s3 —>堆中的对象 —>常量池中的字符串。
s3指向的是堆中的对象,明显s1与s3指向的地址不同,所以返回false。 String s1="abc"; 在编译阶段就被确定, String s3 = new String("abc"); 在运行时才能确定。
java.lang.String类使用了final修饰,不能被继承。Java程序中的所有字面值,即双引号括起的字符串,如"abc",都是作为String类的实例实现的。String是常量,其对象一旦构造就不能再被改变。换句话说,String对象是不可变的,每一个看起来会修改String值的方法,实际上都是创造了一个全新的String对象,以包含修改后的字符串内容,而最初的String对象则丝毫未动。
String s = "abc"; s = "123"; System.out.println("s=" + s); 输出结果: s=123
这里看似变量s被修改了,实际上将s重新指向一个字符串“123”,而不是直接将原来的"abc"修改为"123"。
String s1 = "abc"; String s2 = "ab" + "c"; System.out.println(s1==s2); final String s3 = "ab"; String s4 = s3 + "c"; System.out.println(s1==s4); String s5 = "ab"; String s6 = s5 + "c"; System.out.println(s1==s6); String s7 = new String("ab") + "c"; System.out.println(s1==s7); 输出结果: true true false false
第1,2个结果是true是因为,编译器对那些在编译期就可以确定其值的常量的运算会进行优化,因为s2+号两边是字面量,所以s2在编译期就会被优化为 String s2 = "abc";
对于第3、4个结果,运算中存在变量,虚拟机对+的运算就会被解析为StringBuilder(或 StringBuffer)类及其 append 方法实现的,再通过toString 方法转换为字符串,所以s6相当于 s6=new StringBuffer(s5).append("c").toString(),而s6重新指向一个新的StringBuffer对象。
//方式一 String s = "s"; for (int i = 0; i < 20; i++) { s += i; } //方式二 StringBuffer sb = new StringBuffer("s"); for (int i = 0; i < 20; i++) { sb.append(i); }
结合我们平时的应用,如果用String+的方式,每循环一次,就会重新new一个StringBuffer对象,无疑造成了很多不必要的开销,而方式二会更高效一点。
运行速度快慢为:StringBuilder > StringBuffer > String
String与StringBuilder、StringBuffer的区别:
String为字符串常量,即String对象一旦创建之后该对象是不可更改的,前文中对于存在变量的String+操作,实质是new StringBuffer和.toString()操作。而StringBuilder和StringBuffer都可以直接对原对象追加、插入和删除。
StringBuilder与StringBuffer的区别:
StringBuilder是线程不安全的。而StringBuffer是线程安全的 ,StringBuffer中很多方法可以带有synchronized关键字。
综上,
String:适用于少量的字符串操作的情况
StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况
被final修饰的变量不可变的是变量的引用,而不是引用指向的内容,引用指向的内容是可以改变的。
参考链接:
https://www.cnblogs.com/baihehanqiu/p/6938850.html
http://www.cnblogs.com/avivahe/p/5747127.html
https://segmentfault.com/a/1190000009888357
https://blog.csdn.net/wang854837173/article/details/52439123
https://www.cnblogs.com/qiaoyanlin/p/6877628.html
https://www.cnblogs.com/tianyaxue/p/3145079.html
https://blog.csdn.net/sugar_rainbow/article/details/68150249
http://www.cnblogs.com/roy-mustango/p/4240302.html
https://www.cnblogs.com/hithlb/p/4872373.html
String类型相加
https://blog.csdn.net/changjinglubeipan/article/details/78614969
https://www.zhihu.com/question/35014775
https://baijiahao.baidu.com/s?id=1576306750248354576&wfr=spider&for=pc
关于string的面试题
https://blog.csdn.net/uotail/article/details/71244606
https://blog.csdn.net/nwpu_geeker/article/details/78701343
StringBuffer
https://www.cnblogs.com/su-feng/p/6659064.html
final
https://www.jianshu.com/p/17becea7942d
https://www.cnblogs.com/dolphin0520/p/3736238.html
https://www.cnblogs.com/xh0102/p/5729381.html
JVM理论:(三/8)关于String、StringBuffer、StringBuilder、final
标签:描述 title uga any 修改 equals 也会 tle https
原文地址:https://www.cnblogs.com/zjxiang/p/9379676.html