Day2_Java進階_Java反射【特別重要】

2020.7.6 10:37:00

一、反射概述

示例1:不同的人通過X光機得到類似的影像資料。在影像資料中包含人體的各個組成部分。
在這裏插入圖片描述
示例2:學生類Student和老師類Teacher要想使用需先通過類加載器加載爲對應的.class文件到內存。在.class文件中包含了成員方法、構造方法、成員變量等等一些相似的信息。Class是所有的.class文件對象所對應的類型。也就是說是所有類的影像。
我們可直接通過Class類獲取所有類的成員方法、構造方法等信息,而不是去找到Student類或其他類來得到這些信息。

在這裏插入圖片描述

Java反射機制:是指在運行時去獲取一個類的變量和方法信息。然後通過獲得到的信息來創建對象,調用方法的一種機制
由於這種動態性,可以極大的增加程序的靈活性,程序在不用在編譯期就完成確定,在運行期仍然可以拓展。

二、反射獲取Class類的對象的三種方式

我們要想通過反射去使用一個類,首先我們需要獲取到該類的字節碼文件的對象,也就是類型爲Class類型的對象。

這裏我們提供了三種方式來獲取Class類的對象:

  1. 使用類的class屬性來獲取該類對應的Class對象
    舉例:Student.class將會返回Student類對應的Class對象。
  2. 調用對象的getClass()方法來 返回該對象所屬類對應的Class對象
    getClass() 方法是Object類中的方法,所有的Java對象都可以調用該方法。
  3. 使用Class類中的靜態方法forName(String className),該方法需要傳入字符串參數,該字符串參數的值爲某個類的全路徑,也就是完整包名的路徑。
    示例:

①新建一個Student類:

package com.hoqis;

/**
 * @author HoQis
 * @create 2020-07-06 14:30
 */
public class Student {
    //成員變量:一個私有、一個默認、一個公共
    private String name;
    int age;
    public String address;

    //構造方法,一個私有、一個默認、兩個公共
    public Student() {
    }

    private Student(String name){
        this.name=name;
    }

    Student(String name, int age){
        this.name = name;
        this.age = age;
    }

    public Student(String name, int age, String address){
        this.name = name;
        this.age = age;
        this.address = address;
    }

    //成員方法:一個私有、四個公共
    private void function(){
        System.out.println("function!!!");
    }

    public void method1(){
        System.out.println("method1");
    }

    public void method2(String s){
        System.out.println("method2"+s);
    }
    public String method3(String s,int i){
        return s+","+i;
    }

    @Override
    public String toString() {
        return "ReflectClass_Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                '}';
    }
}

②新建一個獲取Student類的ReflectDemo類。分別介紹了三種方式來獲取Class類對象。

package com.hoqis;
/**
 * @author HoQis
 * @create 2020-07-06 11:25
*/

/*
三種方式來獲取Class對象
    1.使用類的class屬性來獲取該類對應的Class對象
    2.調用對象的getClass()方法來獲取所屬類對應的Class對象
    3.使用Class類中的靜態方法forName(String className),需傳入字符串參數,該參數爲某個類的全路徑【完整包名】
 */
public class ReflectDemo {
    public static void main(String[] args) throws ClassNotFoundException {
        //1.使用類的class屬性來獲取該類對應的Class對象
        Class<Student> c1 = Student.class;
        System.out.println("使用類的class屬性來獲取該類對應的Class對象:"+c1);

        Class<Student> c2 = Student.class;
        System.out.println(c1==c2);
        System.out.println("---------------------------");
        
        //2.調用對象的getClass()方法來返回該對象所屬類對應的Class對象
        Student student = new Student();
        Class<? extends Student> c3 = student.getClass();
        System.out.println(c1==c3);
        System.out.println("---------------------------");

        //3.使用Class類中的靜態方法forName(String className)
        Class<?> c4 = Class.forName("com.hoqis.Student");
        System.out.println(c1==c4);
    }
}

控制檯打印得到的結果爲:

使用類的class屬性來獲取該類對應的Class對象:class com.hoqis.Student
true
---------------------------
true
---------------------------
true

Process finished with exit code 0

【總結】說明這三種方式都能夠正常獲取到該類對應的Class對象。

三、反射獲取構造方法並使用

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章