== 和 equals 的区别,String常量池
先说string的特别之处。和常量池。
常量池参考:https://www.cnblogs.com/jssj/p/14317361.html
- == : 如果判断数值类型的变量,就是判断变量的值是否相等。
- == :如果判断引用类型变量,就是判断引用类型变量指向的内存地址的值否相同。
- equals:比较引用类型时,默认也是比较引用类型变量的地址值是否相同,因为Object类equals方法里面实际上用的也是 ==。
- String类的equals:String类重写了equals方法,String的equals方法重写成了判断String的值value是否相同。
String类的toString()方法源码:
常量池,Java8 常量池是在堆内存中的。
练习一下:
//代码块1
String s1 = new StringBuilder().append("java").append("String").toString();
String s2 = s1.intern();
System.out.println("s1==s2:"+(s1==s2));
//代码块2
String s5 = "spring1";
String s3 = new StringBuilder().append("spring").append("1").toString();
String s4 = s3.intern();
System.out.println("s3==s4:"+(s3==s4));
System.out.println("s4==s5:"+(s4==s5));
//代码块3
String s7 = new StringBuilder().append("s").append("pring2").toString();
String s8 = s7.intern();
String s6 = "spring2";
System.out.println("s7==s8:"+(s7==s8));
Java8环境下运行输出结果:
s1=s2:true
s3=s4:false
s4=s5:true
s7=s8:true
是不是费解?
代码中的s3=4 和 s7=s8 不应该是一样的?为什么会不一样呢,跟s5和s6有什么关系,到底过程是怎么样的呢?
首先,在上面的代码块1最头顶处插入一行代码
//代码块1
String s0= "javaString";
String s1 = new StringBuilder().append("java").append("String").toString();
String s2 = s1.intern();
System.out.println("s1==s2:"+(s1==s2)); //此时此处输出false
结合常量池想想为什么?
因为第一行s0指向的String对象已经出现在常量池了,所以第三行代码处s1调用的intern()方法不会再将这个string加入常量池中,而是把常量池已有的string对象的引用返回给s2,所以这时的s2==s0,
而s1呢?s1拿到的引用就和String s1 = new String(“javaString”)一样,可以看StringBuilder的toString()方法了;
同理反推:代码块3
//代码块3
String s7 = new StringBuilder().append("s").append("pring2").toString();
String s8 = s7.intern();
String s6 = "spring2";
System.out.println("s7==s8:"+(s7==s8));
s7.intern()方法执行时,成功将字符串spring2放进常量池中,那s6拿到的其实就是常量池中的同一个spring2字符串。
其实代码块3这里s6 , s7 , s8都是指向同一个内存地址的。
话题2:String是不可变字符串?
参考文章:https://blog.csdn.net/zhangjg_blog/article/details/18319521#