如何在Java中建立包含可變物件引用的不可變類?\n
不可變物件是指其狀態一旦初始化後就不能更改的物件。有時根據需要建立不可變類是必要的。例如,所有基本包裝類(Integer、Byte、Long、Float、Double、Character、Boolean 和 Short)在 Java 中都是不可變的。String 類也是一個不可變類。
要建立自定義不可變類,我們需要執行以下步驟
- 將類宣告為final,以便它不能被擴充套件。
- 將所有欄位設為私有,以便不允許直接訪問。
- 不要為變數提供setter 方法(修改欄位的方法),以便它不能被設定。
- 將所有可變欄位設為final,以便它們的值只能分配一次。
- 透過執行深度複製的建構函式初始化所有欄位。
- 在 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
廣告