Java 中的不可变类以及不可变类的设计好处

Java 中的不可变类以及不可变类的设计好处

 

 

1、简介

         不可变类(immutable class)是指当创建了这个类的实例后,就不允许修改它的值了。也就是说,一个对象一旦被创建出来,在其整个生命周期中,它的成员变量就不能被修改了。它有点类似于常量(const),即只允许别的程序读,不允许别的程序进行修改。在Java类库中,所有基本类型的包装类都是不可变类,例如Integer、Float等。此外,String也是不可变类。共享元素模式,也就是说:一个系统中如果有多处用到了相同的一个元素,那么我们应该只存储一份此元素,而让所有地方都引用这一个元素。Java中String就是根据享元模式设计的,而那个存储元素的地方就叫做 "字符串常量池——String Pool"。

 

2、String 类被设计成不可变的好处

我们来看看字符串不可变性的一些好处,这些好处有助于我们来理解为什么 String 在 java 中是不可变的:

1、性能:由于 String 在 Java 中是不可变的,这样 Java Runtime 就可以节省大量的 Java 堆空间,因为不同的 String 变量可以在String Pool中引用相同的 String 变量(实际String对象的值)。
2、性能:由于 String 是不可变的,它的 hashcode 在创建时就被缓存了,它不需要再次计算,并且它的处理速度比其他 Object对象要快。这也是为什么 HashMap 常用 String 对象作 key的原因。
3、安全:如果String不是不可变的,那么它将对应用程序造成严重的安全威胁。 例如,数据库用户名,密码作为String传递以获取数据库连接.如果String是可变的,黑客可以轻松改变它的引用值以导致应用程序中出现安全问题。
4、安全:由于String是不可变的,所以它在多线程环境(multithreading)是线程安全的,一个 String 实例可以在不同的线程中共享。 这避免了使用同步(synchronization)来保护线程安全,String是隐式线程安全的.
5、安全:String被用在了classloader 类加载器中,不可变性提供了正确的类由Classloader加载的安全性。 例如,假设您尝试加载java.sql.Connection类的实例,但引用的值更改为myhacked.Connection类,可以对数据库执行有害的操作。

 

3、如何创建一个不可变类?

通常来讲,要创建一个不可变类需要遵循下面4条基本原则:

1、类中所有成员变量被private所修饰。
2、类中没有写或者修改成员变量的方法,例如set**,只提供构造方法,一次生成,永不改变。
3、确保类中所有方法不会被子类覆盖,可以通过把类定义为final或者把类中的方法定义为final来达到这个目的。
4、如果有必要,可以使用覆盖Object类的equals()方法和hashCode()方法。在equals()方法中,根据对象的属性值来比较两个对象是否相等,并且保证用equals()方法判断为相等的两个对象的hashCode()方法返回值也相等,这可以保证这些对象能被正确地放到HashMap或者HashSet集合中。

 

posted @ 2022-05-24 15:00  邓维-java  阅读(274)  评论(0)    收藏  举报