一、不可变对象理解
1. 什么是不可变对象
不可变对象是指对象被创建之后,其内部状态保存不变的对象(内部成员变量值不会被改变,因为没有set方法)。这意味着其公开的API保证在对象的整个生命周期中其行为保持一致。
可变不可变其实质是:地址里面的值可变还是不可变
不可变的原因有:无set方法,则里面存储值无法改变
可变原因:1.有set方法实现
2.在set方法里面可以重新new一个对象。new对象是在堆内存中重新分配,则地址会改变
下面我们看看String类,即使我们使用其replace api提供了一个可变的行为,但其原字符串并没有改变:
String name = "baeldung";
String newName = name.replace("dung", "----");
assertEquals("baeldung", name);
assertEquals("bael----", newName);
该API属于只读方法,String中没有改变其内部状态的方法(也就是set方法).
2.对final理解
final String str = new String(“abs”) final不可变指的是 str引用所指向的地址一致不变,但是地址里面的内容是可以改变的,因为他是重新new一个对象
3.不可变对象真的"完全不可改变"吗?
不可变对象虽然具备不可变性,但是不是"完全不可变"的,这里打上引号是因为通过反射的手段是可以改变不可变对象的状态的。
4.字符串常量池
- 在JDK6.0及之前版本,字符串常量池是放在Perm Gen区(也就是方法区)中;
- 在JDK7.0版本,字符串常量池被移到了堆中了。至于为什么移到堆内,大概是由于方法区的内存空间太小了
== 比较的是地址,堆中存放对象地址永远不会与常量池中存放对象相等
String str = new String(“dds”)只会将它放入堆中,不会放入到字符串常量池中,当使用str.intern()方法后会将其放入字符串常量池中
String str1 = “dgba” 只会将它放入字符串常量池中堆中,不会放入到堆中
参考:https://blog.csdn.net/neweastsun/article/details/84669273
https://blog.csdn.net/chaoge321/article/details/84327958
https://www.cnblogs.com/dolphin0520/p/10693891.html 非常推荐看:尤其是不可变对象在并发编程中的好处