1. 程式人生 > 實用技巧 >關於類的載入機制和反射機制只看這一篇就夠了,分析的非常詳細

關於類的載入機制和反射機制只看這一篇就夠了,分析的非常詳細

類載入機制的原理

1.啟動JVM
2.將需要執行的class檔案載入到虛擬機器記憶體中
3.找到主類,開始執行主函式

載入步驟:

1.先委託父類載入類,如果父類已經載入,就不需要再次載入,如果父類沒有載入,再由本載入器載入
2.解析類路徑,將類路徑轉換成檔案路徑
3.通過檔案輸入流來讀取class檔案,得到位元組陣列
4.將位元組陣列轉換成類物件,物件的型別是Class型別

有哪些類載入器

類載入器:ClassLoader
AppClassLoader: 應用類載入器,負責載入核心類,載入自己寫的類
ExtClassLoader: 擴充套件類載入器,負責載入擴充套件類庫
bootstrap: JVM內建的載入器
Bootstrap

類載入器是JVM的一部分,是由C++編寫的,隨著啟動虛擬機器就會建立一個bootstrap類載入器物件

獲得Class物件的幾種方式

1.通過類名.class

Class c1 = Student.class;

2.通過物件的getClass()方法

Class c2 = stu.getClass();

3.通過類載入器獲得class物件

ClassLoader classLoader = ClassLoader.getSystemClassLoader();
Class c3 = classLoader.loadClass("com.newer.test.Student");

4.通過 Class.forName()獲得Class物件;

Class c4 =  Class.forName("com.newer.test.Student");

總程式碼:
先建立學生類

package com.newer.test;

public class Student {
    private int num;
    private String name;
    private int age;
    public Student(){
    }
    private Student(int num){
        this.num = num;
    }
    public Student(int num,String name,int age){
        this.num = num;
        this.name = name;
        this.age = age;
    }
    public int getNum() {
        return num;
    }
    public void setNum(int num) {
        this.num = num;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Student{" +
                "num=" + num +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
package com.newer.test;

public class MainClass {
    public static void main(String[] args) throws  Exception{

        Student stu = new Student();

        //獲得Student的Class物件

        //1.通過類名.class
        Class c1 = Student.class;

        //2.通過物件的getClass()方法
        Class c2 = stu.getClass();

        //3.通過類載入器獲得class物件
        ClassLoader classLoader = ClassLoader.getSystemClassLoader();
        Class c3 = classLoader.loadClass("com.newer.test.Student");

        //4.通過 Class.forName()獲得Class物件;
        Class c4 = Class.forName("com.newer.test.Student");

如何通過Class物件獲得構造方法物件

類的所有的資訊都在Class物件中
Class類是反射機制中的核心類

Class c = Class.forName(包名.類名);

//載入類,獲得類的Class物件
Class c = Class.forName("com.newer.test.Student");

1.獲得所有可見的構造方法

//1.獲得所有可見的構造方法
Constructor[] cons= c.getConstructors();

2.獲得所有已經宣告的構造方法

//2.獲得所有已經宣告的構造方法
Constructor[] cons2= c.getDeclaredConstructors();

3.獲得指定的可見的某一個構造方法

//3.獲得指定的可見的某一個構造方法
Constructor cc = c.getConstructor(int.class,String.class,int.class);

4.從宣告的方法中獲得指定的構造方法

//4.從宣告的方法中獲得指定的構造方法
Constructor cc2 = c.getDeclaredConstructor(int.class);

總程式碼:
學生類

package com.newer.test;

public class Student {
    private int num;
    private String name;
    private int age;
    public Student(){
    }
    private Student(int num){
        this.num = num;
    }
    public Student(int num,String name,int age){
        this.num = num;
        this.name = name;
        this.age = age;
    }
    public int getNum() {
        return num;
    }
    public void setNum(int num) {
        this.num = num;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Student{" +
                "num=" + num +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

package com.newer.test;

import java.lang.reflect.Constructor;
/**
 * 反射機制動態獲得類的資訊
 */
public class FanShe {
    public static void main(String[] args) throws Exception{
        //載入類,獲得類的Class物件
        Class c = Class.forName("com.newer.test.Student");
        //通過Class物件獲得類的資訊
        //1.獲得所有可見的構造方法
        Constructor[] cons= c.getConstructors();
        for (Constructor con:cons){
            System.out.println(con);
        }
        System.out.println("------------------------");
        //2.獲得所有已經宣告的構造方法
        Constructor[] cons2= c.getDeclaredConstructors();
        for (Constructor con:cons2){
            System.out.println(con);
        }
        System.out.println("------------------------");
        //3.獲得指定的可見的某一個構造方法
        Constructor cc = c.getConstructor(int.class,String.class,int.class);
        System.out.println(cc);
        System.out.println("------------------------");
        //4.從宣告的方法中獲得指定的構造方法
        Constructor cc2 = c.getDeclaredConstructor(int.class);
        System.out.println(cc2);
        System.out.println("------------------------");
      }
}

如何通過構造方法物件例項化

//通過構造方法物件得到類的例項物件
Object obj = cc.newInstance(123,"zhangsan",20);

訪問私有構造方法:
cc2.setAccessible(true);

//通過私有構造方法例項化物件
//設定允許訪問私有構造方法
cc2.setAccessible(true);
Object obj2 =  cc2.newInstance(22);

最後

感謝你看到這裡,看完有什麼的不懂的可以在評論區問我,覺得文章對你有幫助的話記得給我點個贊,每天都會分享java相關技術文章或行業資訊,歡迎大家關注和轉發文章!