構造函數
用於給對象進行初始化
構造函數沒有返回值(不是void)
構造函數無法用final、static修飾符修飾
不能被繼承,因此不能被重寫,但是可以重載
構造函數在對象初始化時就執行了,並且只執行一次
定義的每一個類中都有一個默認的空參構造函數,一旦自定義了構造函數後,默認的空參構造函數就沒有了,需要顯式加上空參構造函數(不是必須,但是最好加上)
當父類中沒有空參的構造函數時,子類的構造函數需要顯示指明要訪問的父類構造函數 super(…),並且該語句必須在子類構造函數的第一行,因爲父類要先初始化完成。
this()、super()同時作用於構造函數的調用時不能同時存在。
構造函數只能被構造函數調用並且只能定義在第一行,this()
public class Test{
private String name;
public Test() {
this("zhangsan");
}
public Test(String name) {
// 隱式調用了父類構造函數
this.name = name;
}
}
創建對象and初始化
對象創建的流程
1.加載指定的字節碼文件進內存
2.通過new在堆中開闢空間分配首地址值
3.對成員屬性進行默認初始化
4.調用對應的構造函數,構造函數壓棧,執行對應的初始化代碼
5.初始化完畢將地址值賦值給指定的引用
對象初始化過程
1.先執行父類中的靜態成員變量和靜態代碼塊
2.子類的靜態成員變量和靜態代碼塊
3.父類的普通成員變量和構造代碼塊,構造函數
4.子類的普通成員變量和構造代碼塊,構造函數
執行順序:父類靜態成員變量 > 父靜態代碼塊 > 子類靜態成員變量 > 子靜態代碼塊 > 父類成員屬性 > 父構造代碼塊 > 父構造函數 > 子類成員屬性 > 子類構造代碼塊 > 子類構造函數
public class Father {
public static String NAME_STATIC = "father static";
public String name = "father";
static {
System.out.println("static code block father:" + NAME_STATIC);
}
{
System.out.println("construct code block father:" + name);
}
public Father() {
System.out.println("construct method father");
}
}
public class Sub extends Father {
public static String NAME_STATIC = "sub static";
public String name = "sub";
static {
System.out.println("static code block sub:" + NAME_STATIC);
}
{
System.out.println("construct code block sub:" + name);
}
public Sub() {
System.out.println("construct method sub");
}
public static void main(String[] args) {
new Sub();
}
}
創建對象的幾種方式
1.使用new關鍵字
2.Calss.forName(“全路徑類名”).newInstance(); 只能調用無參構造函數,若無默認的無參構造函數則會報InstantiationException異常
3.Class.getConstructor(Class<?>… parameterTypes).newInstance(Object … initargs);有參無參都可以調用
4.實現Cloneable接口重寫clone方法
5.序列化和反序列化
// 1
new Date();
// 2
try {
Class.forName("java.util.Date").newInstance();
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
e.printStackTrace();
}
// 3
try {
Date.class.getConstructor().newInstance();
Date.class.getConstructor(long.class).newInstance(12345676L);
} catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
// 4
new Date().clone();