前言
做Java開發(fā)將近一年半了,雖然之前系統(tǒng)地學(xué)習(xí)過Java,但是實踐出真知,最近總感覺還有好多知識點(diǎn)沒有掌握,尤其是看大神寫的代碼,經(jīng)常會還有如此操作的感嘆。于是又沿著《Java核心編程技術(shù)卷一》這本書重新學(xué)習(xí)下Java,讀了一部分,發(fā)現(xiàn)學(xué)習(xí)了到了很多,以前不太理解的東西也瞬間懂了。一些自己感覺容易忘記,或者不太好理解的知識點(diǎn),記下來以備后用。
類初始化的條件
我們知道類從被加載到虛擬機(jī)內(nèi)存中開始,到卸載出內(nèi)存中為止,它的整個生命周期包括:加載(Loading)、驗證(Verification)、準(zhǔn)備(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸載(Unloading)7個階段。這7個階段的發(fā)生順序如下圖所示。
對于類初始化來說,JVM規(guī)范嚴(yán)格規(guī)定了有且只有5中情況必須立即對類進(jìn)行初始化。
1) 使用new關(guān)鍵字實例化對象的時候、 讀取或設(shè)置一個類的靜態(tài)字段(被final修飾、已在編譯器把結(jié)果放入常量池的靜態(tài)字段除外)的時候、調(diào)用一個類的靜態(tài)方法的時候的時候。
2) 使用java.lang.reflect包的方法對類進(jìn)行反射調(diào)用的時候,如果類沒有進(jìn)行過初始化,則需要先觸發(fā)其初始化。
3) 初始化子類時,先對其父類進(jìn)行初始化。
4) 虛擬機(jī)啟動時,先初始化主類(包含main()方法的那個類)
5) 看不懂這一條,略過
初始化順序
package com.resum.javabase;
import java.util.Random;
public class ConstructorTest {
public static void main(String[] args) {
Manager manager = new Manager("laozhang", 15000);
double salary = manager.getSalary();
System.out.println(salary);
}
}
class Employee {
private static int nextId;
private int id;
private String name = "";//5
private double salary;
public static final String address = "Shanghai";
static {//1
Random rand = new Random();
nextId = rand.nextInt(1000);
}
{//6
id = nextId;
nextId++;
salary = 8000;
}
public Employee(String name, double salary) {//4
this.name = name;//7
this.salary = salary;
}
public Employee(double salary) {
this("Employee#" + nextId, salary);
}
public Employee() {//3
}//6
public String getName() {
return this.name;
}
public double getSalary() {
return this.salary;
}
public int getId() {
return this.id;
}
}
class Manager extends Employee {
private double bonus;
public static String ip;
public static final String address = "BeiJing";
static {
ip = "192.168.0.0.1";//2
}
{
bonus = 100;//8
}
public Manager(String name, double salary) {
super(name, salary);//3
}//9
public double getSalary() {
return super.getSalary() + this.bonus;
}
}
總結(jié)
非繼承關(guān)系類初始化順序
靜態(tài)成員和static塊->普通成員和非static塊->構(gòu)造函數(shù)
繼承關(guān)系類初始化順序
父類靜態(tài)成員和static塊->子類靜態(tài)成員和static塊->父類普通成員和非static塊->父類構(gòu)造函數(shù)->子類普通成員和非static塊->子類構(gòu)造函數(shù)