大家好,我是哪吒。
package com.nezha.javase;
public class Person1 {
private int personId;
public Person1() {
setId(100);
}
public void setId(int id) {
personId = id;
}
}
package com.nezha.javase;
public class Student1 extends Person1 {
private int studentId = 1;
public Student1() {
}
@Override
public void setId(int id) {
super.setId(id);
studentId = id;
}
public void getStudentId() {
System.out.println("studentId = " + studentId);
}
}
package com.nezha.javase;
public class Test1 {
public static void main(String[] args) {
Student1 student = new Student1();
System.out.println("new Student() 完畢,開始呼叫getStudentId()方法");
student.getStudentId();
}
}
有興趣的小夥伴試一下,相信我,用System.out.println
標記一下每個函數執行的先後順序,如果你全對了,下面的不用看了,大佬。
package com.nezha.javase;
public class Person {
private int personId;
/**
* 第一步,走父類別無參建構函式
*/
public Person() {
// 1、第一步,走父類別無參建構函式
System.out.println("第一步,走父類別無參建構函式");
System.out.println("");
setId(100);
}
/**
* 第三步,通過super.setId(id);走父類別發方法
* @param id
*/
public void setId(int id) {
System.out.println("第三步,通過super.setId(id);走父類別發方法~~~id="+id);
personId = id;
System.out.println("在父類別:studentId 被賦值為 " + personId);
System.out.println("");
}
}
package com.nezha.javase;
public class Student extends Person {
private int studentId = 1;
/**
* 在走子類無參建構函式前,會先執行子類的普通成員變數初始化
* 第五步,走子類無參建構函式
*/
public Student() {
System.out.println("第五步,在走子類無參建構函式前,會先執行子類的普通成員變數初始化");
System.out.println("第六步,走子類無參建構函式");
System.out.println("");
}
/**
* 第二步,走子類方法
*
* 走完super.setId(id);,第四步,再回此方法
* @param id
*/
@Override
public void setId(int id) {
System.out.println("第二步,走子類方法~~id="+id);
// 3、第三步,走子類方法
super.setId(id);
studentId = id;
System.out.println("第四步,再回此方法,在子類:studentId 被賦值為 " + studentId);
System.out.println("");
}
/**
* 第六步,走getStudentId()
*/
public void getStudentId() {
// 4、列印出來的值是100
System.out.println("第七步,走getStudentId()");
System.out.println("studentId = " + studentId);
System.out.println("");
}
}
package com.nezha.javase;
public class Test1 {
public static void main(String[] args) {
Student1 student = new Student1();
System.out.println("new Student() 完畢,開始呼叫getStudentId()方法");
// 列印出來的值是100
System.out.println("#推測~~列印出來的值是100");
student.getStudentId();
}
}
下面通過圖解JVM的方式,分析一下。
(1)驗證(Verify)
(2)準備(Prepare)
(3)解析
JVM類載入器包括兩種,分別為引導類載入器(Bootstrap ClassLoader)和自定義類載入器(User-Defined ClassLoader)。
所有派生於抽象類ClassLoader的類載入器劃分為自定義類載入器。
類載入器子系統負責從檔案系統或網路中載入class檔案,class檔案在檔案開頭有特定的檔案標識。
ClassLoader只負責class檔案的載入,至於它是否可以執行,則有執行引擎決定。
載入的類資訊存放於一塊稱為方法區的記憶體空間。除了類的資訊外,方法區中還會存放執行時常數池的資訊,可能還包括字串字面量和數位常數(這部分常數資訊是class檔案中常數池部分的記憶體對映)。
類的初始化步驟,這看似非常基礎的話題,卻實打實的難住了很多人,還總結了更為深入JVM的類的載入過程、類載入器的分類、類載入器的作用。