不变的阶级

在这里,我为一些重要的不可变类提供答案。
1.什么是不可变类?
答: 不变的对象s are those objects whose state can not be changed once created. Class whose objects possess 这个 characteristic can be termed as immutable 类.
例如:String,Integer。
2.创建不可变类的步骤是什么?
- 使您的班级最终:
如果将您的课程定为最终课程,则没有课程将无法对其进行扩展,因此将无法覆盖此类的方法。 - 用private和final声明所有实例变量:
如果将实例变量设为私有,则没有外部类将能够访问实例变量,如果将它们设为最终变量,则无法对其进行更改。 - 对设置方法说不:
唐’不能为任何实例变量创建设置方法,因此将没有明确的方法来更改实例变量的状态。 - 初始化构造函数中的所有变量:
您可以在构造函数中初始化变量。使用可变对象时,需要特别注意。如果对象不可变,则需要进行深度复制。 - 从getter方法返回时,执行可变对象的克隆:
如果您从getter方法返回对象的克隆,它将赢得’t返回原始对象,因此原始对象将保持不变。
阅读: 为什么String在Java中是不可变的
3.您能回答以下员工类别是否不变吗?如果不是,您将怎么做使其不可变?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
包 组织.Arpit.爪哇2blog.豆; 进口 爪哇.实用程序.数组列表; 上市 最后 类 雇员 { 私人的 最后 串 名称; 私人的 最后 数组列表 地址; 上市 雇员(串 名称, 数组列表 地址) { 超(); 这个.名称 = 名称; 数组列表 临时添加=新 数组列表(); 对于 (整型 i = 0; i < 地址.尺寸(); i++ ) { 临时添加.加(地址.得到(i)); } 这个.地址 = 临时添加; } 上市 串 得到Name() { 返回 名称; } 上市 数组列表 得到Addresses() { 返回 地址; } } |
回答:
1 2 3 4 5 |
上市 数组列表 得到Addresses() { 返回 (数组列表) 地址.克隆(); } |
4.您能否提供不可变类的示例?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
包 组织.Arpit.爪哇2blog.豆; 进口 爪哇.实用程序.数组列表; 上市 最后 类 国家 { //声明的私有最终实例变量 私人的 最后 串 国家的名字; //可变对象 私人的 最后 数组列表 listOfStates; 上市 国家(串 国家的名字, 数组列表 listOfStates) { 超(); 这个.国家的名字 = 国家的名字; //为可变对象创建深层副本 数组列表 临时列表 = 新 数组列表(); 对于 (整型 i = 0; i < listOfStates.尺寸(); i++ ) { 临时列表.加(listOfStates.得到(i)); } 这个.listOfStates = 临时列表; } 上市 串 得到CountryName() { //不需要克隆,因为它是不可变的对象 返回 国家的名字; } 上市 数组列表 得到ListOfStates() { //返回克隆的对象 返回 (数组列表) listOfStates.克隆(); } } |
5.不变类线程安全吗?如果是,那怎么办?
不可变类是线程安全的,因为您不能更改不可变对象的状态,因此即使两个线程并行访问不可变对象,它也不会’t create any issue.
6.如果使用可变实例变量,需要采取哪些预防措施?
如果您正在使用可变实例变量(上述Employee类中的地址列表),请执行以下操作:
- 在构造函数中深度复制可变变量。
- 返回 从实例变量的getter克隆实例变量 而不是实际变量。
7.为什么不变对象被认为是HashMap的好键?
答: 不变的对象’s hashcode won’更改,因此可以更快地检索密钥,因为您可以为不同的密钥缓存不同的哈希码。对于可变对象,哈希码可能依赖于可变字段,如果这些字段的任何值发生变化,则哈希码可能会更改,因此您可能无法在HashMap中找到键,因为哈希码现在有所不同。
Comments
嗨Arpit,很棒的文章。您是否还应该将clone()用于arraylist的深层复制?对于此行:
临时列表.add(listOfStates.get(i))?还是假设该列表是字符串列表?谢谢
嗨,高兰,
我假设该列表是字符串列表。由于String在Java中是不可变的,因此您不必’无需对ArrayList使用深层复制。
谢谢!!