如何在 Java 中创建具有可变对象引用的不可变类?\
javaobject oriented programmingprogramming更新于 2025/5/22 9:16:17
不可变对象是指那些一旦初始化就无法更改状态的对象。有时需要根据要求创建一个不可变类。例如,Java 中的所有原始包装器类(Integer、Byte、Long、Float、Double、Character、Boolean 和 Short)都是不可变的。 String 类也是一个不可变类。
要创建自定义不可变类,我们必须执行以下步骤
- 将类声明为final,这样它就无法扩展。
- 将所有 字段设为私有,这样就不允许直接访问。
- 不要为变量提供setter 方法(修改字段的方法),这样就无法设置变量。
- 将所有可变字段设为最终,这样它们的值只能分配一次。
- 通过执行深层复制的构造函数初始化所有字段。
- 在 getter 方法中执行对象克隆以返回副本,而不是返回实际对象引用。
- 如果实例字段包含对可变对象的引用,则不允许更改这些对象
- 不要提供修改可变 对象的方法。
- 不要共享对可变对象的引用。切勿存储传递给构造函数的外部可变对象的引用。如有必要,请创建副本并存储对副本的引用。同样,在必要时创建内部可变对象的副本,以避免在我们的方法中返回原始对象。
示例
// Employee.java
final class Employee {
private final String empName;
private final int age;
private final Address address;
public Employee(String name, int age, Address address) {
super();
this.empName = name;
this.age = age;
this.address = address;
}
public String getEmpName() {
return empName;
}
public int getAge() {
return age;
}
/* public Address getAddress() {
return address;
}
*/
public Address getAddress() throws CloneNotSupportedException {
return (Address) address.clone();
}
}
// Address.java
class Address implements Cloneable {
public String addressType;
public String address;
public String city;
public Address(String addressType, String address, String city) {
super();
this.addressType = addressType;
this.address = address;
this.city = city;
}
public String getAddressType() {
return addressType;
}
public void setAddressType(String addressType) {
this.addressType = addressType;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "Address Type - "+addressType+", address - "+address+", city - "+city;
}
}
// MainClass.java
public class MainClass {
public static void main(String[] args) throws Exception {
Employee emp = new Employee("Adithya", 34, new Address("Home", "Madhapur", "Hyderabad"));
Address address = emp.getAddress();
System.out.println(address);
address.setAddress("Hi-tech City");
address.setAddressType("Office");
address.setCity("Hyderabad");
System.out.println(emp.getAddress());
}
}
在上面的例子中,我们不会返回原始的 Address 对象,而是返回该实例的深层克隆副本。地址类必须实现 Cloneable 接口。
输出
Address Type - Home, address - Madhapur, city - Hyderabad Address Type - Home, address - Madhapur, city - Hyderabad
相关文章
有用资源
java 参考教程 - 该教程包含有关 java 的更多信息:https://www.cainiaomax.com/java/

