Java的不可变类(Immutable class)使用

不可变类(Immutable class)

不可变类(Immutable class)是指当一个对象被创建出来以后,它的值就不能被修改了,也就是说,一个对象一旦被创建出来,在其整个生命周期中,它的成员变量就不能被修改了。它有点类似于常量(const),只允许别的程序读,而不允许别的程序进行修改。

在Java类库中,所有基本类型的包装类都是不可变类,例如Integer、Float等。此外,String也是不可变类。可能有人会有疑问,既然 String 是不可变类,那么为什么还可以写出如下代码来修改String类型的值呢?

public class Test
{
    
        public static void main(String[] args)    {
    
          
		 String s="Hello";      
		 s+=" world";      
		 System.out.println(s);    
 	}
}

程序的运行结果为:
Hello world

表面上看,好像是修改String类型对象s的值。其实不是,Strings=“Hello”语句声明了一个可以指向String类型对象的引用,这个引用的名字为s,它指向了一个字符串常量“Hello”。s+=" world"并没有改变s所指向的对象(由于“Hello”是String类型的对象,而String又是不可变量),这句代码运行后,s指向了另外一个String类型的对象,该对象的内容为“Hello world”。原来的那个字符串常量“Hello”还存在与内存中,并没有被改变。

原则

1)类中所有的成员变量被private所修饰。

2)类中没有写或者修改成员变量的方法,例如:setxxx。只提供构造函数,一次生成,永不改变。

3)确保类中所有的方法不会被子类覆盖,可以通过把类定义为 final 或者把类中的方法定义为final来达到这个目的。

4)如果一个类成员不是不可变量,那么在成员初始化或者使用get方法获取该成员变量是需要通过clone方法,来确保类的不可变性。

5)如果有必要,可以通过覆盖 Object 类的 equals()方法和hashCode()方法。在 equals()方法中,根据对象的属性值来比较两个对象是否相等,并且保证用 equals()方法判断为相等的两个对象的hashCode()方法的返回值也相等,这可以保证这些对象能正确地放到HashMap或HashSet集合中。

优缺点

优点

在Java语言中,之所以设计有很多不可变类,主要是因为不可变类具有使用简单、线程安全、节省内存等优点

缺点

例如,不可变的对象会因为值的不同而产生新的对象,从而导致无法预料的问题,所以,切不可滥用这种模式。

对于一些敏感的数据(例如密码),为什么使用字符数组存储比使用String更安全?

答案:在Java语言中,String是不可变类,它被存储在常量字符串池中,从而实现了字符串的共享,减少了内存的开支。正因为如此,一旦一个String 类型的字符串被创建出来,这个字符串就会存在于常量池中,直到被垃圾回收器回收为止。

因此,即使这个字符串(比如密码)不再被使用,它仍然会在内存中存在一段时间(只有垃圾回收器才会回收这块内容,程序员没有办法直接回收字符串)。此时有权限访问memory dump(存储器转储)的程序都可能会访问到这个字符串,从而把敏感的数据暴露出去,这是一个非常大的安全隐患。

如果使用字符数组,那么一旦程序不再使用这个数据,程序员就可以把字符数组的内容设置为空,此时这个数据在内存中就不存在了。从以上分析可以看出,与使用 String 相比,使用字符数组,程序员对数据的生命周期有更好的控制,从而可以增强安全性。

猜你喜欢

转载自blog.csdn.net/david2000999/article/details/121450905