如何在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

更新於: 2020年2月6日

11K+ 瀏覽量

開啟你的職業生涯

透過完成課程獲得認證

開始學習
廣告