目錄
一、概念
二、Class 類別
三、取得類別資訊
四、動態呼叫
首頁 Java java教程 Java反射是什麼? Java反射機制的詳細介紹

Java反射是什麼? Java反射機制的詳細介紹

Sep 19, 2018 pm 02:30 PM
java反射

這篇文章帶給大家的內容是關於Java反射是什麼? Java反射機制的詳細介紹,有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

一、概念

    Java 反射(Reflection)就是Java 程式在執行時可以載入一個才知道類別名稱的類,取得類別的完整建構方法,並且實例化出對象,給物件屬性設定值或呼叫物件的方法。這種在運行時動態獲取類別的資訊以及動態呼叫物件的方法的功能稱為 Java 的反射機制。

二、Class 類別

Class 類別繼承自Object 類,是Java 反射機制的入口,封裝了一個類別或介面的執行時間訊息,透過呼叫Class 類別的方法可以取得到這些資訊。怎麼理解這個 Class 類別呢?如果說普通類別是所有物件方法、屬性的集合,那就可以把這個 Class 類別理解成是所有普通類別的集合。

下面列舉了幾個取得Class 類別的方法:

public class TestClass {
    public static void main(String[] args) throws ClassNotFoundException {
        // 1、 Class.forName();
        Class<?> aClass0 = Class.forName("java.lang.Object");
        // 2、类名.Class
        Class<Integer> aClass1 = Integer.class;
        // 3、包装类.TYPE —— 返回基本类型的 Class 引用,基本类型在虚拟机运行时就已经加载了它的Class
        Class<Integer> aClass2 = Integer.TYPE;
        // 4、对象名.getClass()
        String str = "Hello, World";
        Class<? extends String> aClass3 = str.getClass();
        // 5、Class类.getSuperClass() —— 获得父类的 Class 对象
        Class<?> aClass4 = aClass3.getSuperclass();

        System.out.println(aClass0.getName());
        System.out.println(aClass1.getName());
        System.out.println(aClass2.getName());
        System.out.println(aClass3.getName());
        System.out.println(aClass4.getName());
    }
}
登入後複製

三、取得類別資訊

為了測試Java 的反射機制,我新建了一對父子類,其中涵蓋了四種封裝屬性,以盡可能的測試多種類資訊的獲取:

Vehicle.java

vpublic class Vehicle {
    private String color;
    protected Integer seat;
    int year;
    public Date createdOn;
    private String getColor() {
        return color;
    }
    protected Integer getSeat() {
        return seat;
    }
    int getYear() {
        return year;
    }
    public Date getCreatedOn() {
        return createdOn;
    }
}
登入後複製

Car.java

public class Car extends Vehicle {
    private String brand;
    protected Integer a;
    int b;
    public Date updatedOn;
    public Car(){}
    private Car(String brand, Integer a, int b, Date updatedOn) {
        this.brand = brand;
        this.a = a;
        this.b = b;
        this.updatedOn = updatedOn;
    }
    private String getBrand() {
        return brand;
    }
    protected Integer getA() {
        return a;
    }
    int getB() {
        return b;
    }
    public Date getUpdatedOn() {
        return updatedOn;
    }
}
登入後複製

#1、取得方法

Class 類別對方法的取得主要透過以下兩種方式:

Method[] getMethods() 傳回該類別或介面的所有可存取公用方法(含繼承的公共方法)。

Method[] getDeclaredMethods() 傳回該類別或介面的所有方法(不含繼承的方法)。

public class TestMethod {
    public static void main(String[] args) {
        Class<Car> carClass = Car.class;
        Method[] methods = carClass.getMethods();
        Method[] declaredMethods = carClass.getDeclaredMethods();

        for (Method method : methods) {
        //for (Method method : declaredMethods) {
            System.out.println("方法名:" + method.getName());
            System.out.println("该方法所在的类或接口:" + method.getDeclaringClass());
            System.out.println("该方法的参数列表:" + method.getParameterTypes());
            System.out.println("该方法的异常列表:" + method.getExceptionTypes());
            System.out.println("该方法的返回值类型:" + method.getReturnType());
        }
    }
}
登入後複製

2、取得屬性

Class 類別對屬性的取得主要透過以下兩種方式:

Field[] getFields() :存放該類別或介面的所有可存取公共屬性(含繼承的公共屬性)。

Field[] getDeclaredFields():存放該類別或介面的所有屬性(不含繼承的屬性)。

public class TestField {
    public static void main(String[] args) {
        Class<Car> carClass = Car.class;
        Field[] fields = carClass.getFields();
        Field[] declaredFields = carClass.getDeclaredFields();
        //for (Field field : fields) {
        for (Field field : declaredFields) {
            System.out.println("属性名称是:" + field.getName());
            System.out.println("该属性所在的类或接口是:" + field.getDeclaringClass());
            System.out.println("该属性的类型是:" + field.getType());
            // field.getModifiers() 以整数形式返回由此 Field 对象表示的属性的 Java 访问权限修饰符
            System.out.println("该属性的修饰符是:" + Modifier.toString(field.getModifiers()));
        }
    }
}
登入後複製

3、取得建構子

Class 類別對建構方法的取得主要透過以下兩種方式:

Constructor[ ] getConstructors() :傳回該類別或介面的所有的公共建構方法

Constructor[] getDeclaredConstructors():傳回該類別或介面的所有建構方法

public class TestConstructor {
    public static void main(String[] args) throws NoSuchMethodException {
        Class<Car> carClass = Car.class;
        Constructor<?>[] constructors = carClass.getConstructors();
        Constructor<?>[] declaredConstructors = carClass.getDeclaredConstructors();
        Constructor<Car> carConstructor = carClass.getDeclaredConstructor(String.class, Integer.class, Integer.TYPE, Date.class);
        //for (Constructor constructor : declaredConstructors) {
        for (Constructor constructor : constructors) {
            System.out.println("该构造器的名称是:" + constructor.getName());
            System.out.println("该构造器所在的类或接口是:" + constructor.getDeclaringClass());
            //返回构造方法的参数类型
            constructor.getParameterTypes();
        }
    }
}
登入後複製

四、動態呼叫

到目前為止,我們都是透過Class 類別的方法來取得對應類別屬性、方法和建構子的詳細資訊。接下來我們將透過這些訊息,來動態建立物件、修改屬性和動態呼叫方法。

public class Test {
    public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        Class<Car> carClass = Car.class;
        // 1、实例化对象
        // 调用 Class 类的newInstance();要求对应类必须有无参构造函数,相当于 Car car = new Car()
        Car car = carClass.newInstance();
        // 调用构造器的newInstance(Object ... initargs);
        Constructor<Car> declaredConstructor = carClass.getDeclaredConstructor(String.class, Integer.class, Integer.TYPE, Date.class);
        // 取消访问权限控制,即使是 private 权限也可以访问
        declaredConstructor.setAccessible(true);
        Car car1 = declaredConstructor.newInstance("brand", 21, 21, new Date());
        System.out.println(car1.getUpdatedOn());

        // 2、修改属性
        Field brand = carClass.getDeclaredField("brand");
        brand.setAccessible(true);
        System.out.println("取消访问权限控制后的值:" + brand.get(car1));
        brand.set(car1, "dnarb");
        System.out.println("修改属性后的值是:" + brand.get(car1));

        // 3、调用方法
        Method getBrand = carClass.getDeclaredMethod("getBrand");
        getBrand.setAccessible(true);
        System.out.println("调用反射方法得到的值是:" + getBrand.invoke(car1));
    }
}
登入後複製

以上是Java反射是什麼? Java反射機制的詳細介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1665
14
CakePHP 教程
1424
52
Laravel 教程
1322
25
PHP教程
1270
29
C# 教程
1250
24
使用Java反射進行逆向工程:揭秘軟體的內部運作方式 使用Java反射進行逆向工程:揭秘軟體的內部運作方式 Feb 19, 2024 pm 11:20 PM

Java反射是一個強大的工具,它可以讓你存取類別的私有欄位和方法,從而揭露軟體的內部運作方式。這在逆向工程、軟體分析和調試等領域非常有用。要使用Java反射,首先需要匯入java.lang.reflect套件。然後,你可以使用Class.forName()方法來取得一個類別的Class物件。一旦你有了Class對象,你就可以使用各種方法來存取類別的欄位和方法。例如,你可以使用getDeclaredFields()方法來取得類別的所有字段,包括私有字段。你也可以使用getDeclaredMethods()方法

java反射如何取得屬性的值 java反射如何取得屬性的值 Jan 03, 2024 pm 03:05 PM

取得方法:1、建立一個範例對象;2、透過field.get(person)取得了欄位的值,其中person是範例對象,而field是Field對象,表示一個欄位;3、透過setAccessible(true)設定欄位為可存取狀態,即使是私有欄位也可以取得其值;4、遍歷欄位數組,可以取得每個欄位的名稱和對應的值,並列印出來即可。

如何使用java反射取得物件屬性和值 如何使用java反射取得物件屬性和值 Jan 03, 2024 pm 02:43 PM

取得方法:1、建立一個Person類,透過反射取得了該類別的Class物件;2、使用getDeclaredFields方法取得了該類別的所有欄位;3、透過遍歷欄位數組,設定欄位為可存取狀態,然後使用get方法取得欄位的值,並列印欄位名稱和值即可。

java的反射機制原理是什麼 java的反射機制原理是什麼 Jun 21, 2023 am 10:53 AM

Java反射機制原理是,當一個字節碼檔案載入到記憶體的時候,jvm會對該字節碼進行解剖,創建一個對象的Class對象,jvm把字節碼文件資訊都儲存到Class對像中,只要取得到Class對象,就能使用該對象設定對象的屬性或方法等。反射機制是,在運行狀態中對任意一個類,都知道這個類的所有屬性和方法,對於任意一個對象,能夠調用其任意屬性和方法,動態獲取資訊以及動態調用對象方法的功能。

深入理解Java反射機制的原理與應用 深入理解Java反射機制的原理與應用 Dec 23, 2023 am 09:09 AM

深入理解Java反射機制的原理與應用一、反射機制的概念與原理反射機制是指在程式執行時動態地獲取類別的資訊、存取與操作類別的成員(屬性、方法、建構方法等)的能力。透過反射機制,我們可以在程式運行時動態地建立物件、呼叫方法和存取屬性,而不需要在編譯時知道類別的具體資訊。反射機制的核心是java.lang.reflect套件中的類別和介面。其中,Class類別代表一個類別的位元組

如何使用Java反射機制建立物件? 如何使用Java反射機制建立物件? Apr 15, 2024 pm 04:18 PM

透過Java反射機制建立物件步驟如下:載入目標類別:使用Class.forName()方法。取得建構子:使用getDeclaredConstructor()方法。建立物件:使用newInstance()方法傳遞參數。

Java中的NoSuchFieldException異常在哪個場景下出現? Java中的NoSuchFieldException異常在哪個場景下出現? Jun 25, 2023 am 11:51 AM

Java中的NoSuchFieldException異常指的是反射過程中試圖存取不存在的欄位(Field)時拋出的例外狀況。在Java中,反射可以讓我們透過程式碼來操縱程式中的類別、方法、變數等,使得程式具有更高的靈活性和擴充性。但是,在使用反射時,如果存取的欄位不存在,則會拋出NoSuchFieldException異常。 NoSuchFieldException

java反射有哪些呼叫方法 java反射有哪些呼叫方法 Dec 22, 2023 pm 05:09 PM

java反射呼叫方法有:1、Class類別;2、Constructor類別;3、Method類別;4、Field類別;5、ClassLoader類別。詳細介紹:1、Class類,用於取得類別的信息,包括類別的名稱、成員變數和方法等,可以透過Class類的"newInstance()"方法建立類別的實例;2、Constructor類,用於取得建構函數的參數類型、修飾符和返回類型等資訊等等。

See all articles