复制构造函数java_Java中的拷贝构造函数
1.介紹
Java 中的拷貝構造方法是一種使用該類的一個對象構造另外一個對象的構造方法。
當需要拷貝一個帶有多個成員變量的復雜對象或者想構造已存在對象的深拷貝對象時非常有用。
譯者注:本文內容很簡單,但是很實用。拷貝構造方法實戰中用雖然用的不多,但是是一個非常不錯的技巧。
2.如何創造拷貝構造方法
要創建拷貝構造方法,首先需要聲明帶有和本類相同類型的參數構造函數:
public class Employee {
private int id;
private String name;
public Employee(Employee employee) {
}
}
然后,將參數對象的每個屬性都復制給新的實例。
public class Employee {
private int id;
private String name;
public Employee(Employee employee) {
this.id = employee.id;
this.name = employee.name;
}
}
上面的做法屬于淺拷貝。
上面定義的屬性不是int 就是 String, 只包含基本類型和不可變類型,因此使用前拷貝就沒問題。
但是如果類中包含可變類型就要通過該構造函數實現深拷貝。
為了實現深拷貝,我們需要根據原始可變對象類型構造新的實例。
public class Employee {
private int id;
private String name;
private Date startDate;
public Employee(Employee employee) {
this.id = employee.id;
this.name = employee.name;
this.startDate = new Date(employee.startDate.getTime());
}
}
3.拷貝構造方法 VS Clone
在 Java 中,我們還可以使用 clone 方法實現根據已有對象創建新對象。
但是拷貝構造方法更有優勢:
拷貝構造方法實現更簡單。不需要實現 Cloneable 接口,也不需要處理 CloneNotSupportedException
clone 函數返回一個普通的 Object 類型的引用。還需要轉成特定的類型。
在 clone 方法中不能為 final 屬性賦值,但是在拷貝構造方法中就可以。
4.繼承問題
Java 中的拷貝構造方法不會被子類繼承。
因此,如果我們嘗試初始化一個帶有父類引用的子類對象,就會面臨著類型轉換問題。
為了更好地說明這個問題,我們首先創建 Employee的子類型和拷貝構造方法。
public class Manager extends Employee {
private List directReports;
// ... 其他構造方法
public Manager(Manager manager) {
super(manager.id, manager.name, manager.startDate);
this.directReports = directReports.stream()
.collect(Collectors.toList());
}
}
然后,我們聲明一個 Employee 類型的引用指向通過 Manager 構造方法構造的 Manager 實例。
Employee source = new Manager(1, "Baeldung Manager", startDate, directReports);
由于引用類型為 Employee, 如果我們想使用 Manager 的拷貝構造函數就必須將 source 強轉為 Manager 類型。
Employee clone = new Manager((Manager) source);
如果參數不是 Manager 類型,運行時會拋出 ClassCastException。
其中一種避免使用拷貝構造方法時類型轉換的方法是創建一個繼承的拷貝函數:
public class Employee {
public Employee copy() {
return new Employee(this);
}
}
public class Manager extends Employee {
@Override
public Employee copy() {
return new Manager(this);
}
}
在每個類的拷貝函數中調用自己類型的拷貝構造函數即可。
這樣就保證了生成的對象和調用的對象類型相同。
Employee clone = source.copy();
5.結論
本文介紹了拷貝構造方法,給出了避免使用 clone 函數的原因。
如果引用類型為父類型而實際對象類型為子類型時,使用子類型的拷貝構造函數需要將父類型強制類型轉換為子類型,容易出現轉換問題。本文也針對這個問題提供了解決方案。
如果你覺得本文對你有幫助,歡迎點贊、轉發、評論,你的支持是我創作的最大動力。
另外想學習,更多開發和避坑技巧,少走彎路,請關注我的專欄:《阿里巴巴Java 開發手冊》詳解專欄
總結
以上是生活随笔為你收集整理的复制构造函数java_Java中的拷贝构造函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [python][原创]全屏截图的4种方
- 下一篇: Java构造函数(构造方法)的简介说明