Java基礎— —反射
阿新 • • 發佈:2021-01-30
Java基礎— —反射
本文主要介紹Java反射相關知識。
文章目錄
一、什麼是反射
Java 反射機制在程式執行時,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意一個方法和屬性。這種 動態的獲取資訊 以及 動態呼叫物件的方法 的功能稱為 java 的反射機制。
二、獲取Class物件
一般通過下述三種方法獲取相應的Class物件:
-
Class.forName(“全限定類名”)
-
類名.class
-
物件.getClass()
一個類只有一個Class物件。
三、使用Class物件
3.1 獲取類名
我們可以使用Class物件的getName()
方法獲取類名。
3.2 獲取成員變數
當建立了一個Class物件後,我們可以使用以下方法獲取成員變數:
方法 宣告 | 解釋 |
---|---|
Field getField(String name) | 獲取指定名稱的公共(public)成員變數。 |
Field[] getFields() | 獲取所有的公共(public)成員變數。 |
Field getDeclaredField(String name) | 獲取指定名稱的成員變數,不再限制訪問修飾符。 |
Field[] getDeclaredFields() | 獲取所有的成員變數,不再限制訪問修飾符。 |
當獲取成員變數物件後
- 可以通過
get(Object obj)
獲取相應物件的值 - 也可以通過
set(Object obj,Object value)
設定相應物件的值。注意,如果修改私有成員變數,需要先忽略訪問許可權修飾符的安全檢查,使用Field
的方法setAccessible(true)
進行設定。
3.3 獲取構造方法
當建立了一個Class物件後,我們可以使用以下方法獲取構造方法:
方法 說明 | 解釋 |
---|---|
Constructor<T> getConstructor(Class<?>... parameterTypes) | 獲取指定引數型別的公共構造方法 |
Constructor<?>[] getConstructors() | 獲取所有的公共構造方法。 |
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) | 獲取指定引數型別的任意構造方法,不再限制訪問修飾符。 |
Constructor<?>[] getDeclaredConstructors() | 獲取所有的構造方法,不再限制訪問修飾符 |
下面通過例子來解釋什麼是指定引數型別的構造方法:
首先宣告一個Student
類:
package com.lee.basic.reflect;
import java.time.LocalDate;
public class Student {
private String name; //姓名
private String studentNumber; //學號
private LocalDate birthday; //出生日期
private String major; //專業
//無參建構函式
public Student() { }
//全參建構函式
public Student(String name, String studentNumber, LocalDate birthday, String major) {
this.name = name;
this.studentNumber = studentNumber;
this.birthday = birthday;
this.major = major;
}
//有姓名和出生日期的建構函式
public Student(String name, LocalDate birthday) {
this.name = name;
this.birthday = birthday;
}
//有姓名和學號的建構函式
public Student(String name, String studentNumber) {
this.name = name;
this.studentNumber = studentNumber;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", studentNumber='" + studentNumber + '\'' +
", birthday=" + birthday +
", major='" + major + '\'' +
'}';
}
}
在測試方法中測試通過反射獲取構造方法:
/**
* 測試通過反射獲取構造方法
*/
@Test
public void testGetConstructor() throws NoSuchMethodException {
Class<Student> studentClass = Student.class;
Constructor<Student> constructor = studentClass.getConstructor(String.class, LocalDate.class);
System.out.println(constructor);
}
結果:
由於構造方法名都是與類名相同,為了區分不同的構造方法,需要指定引數型別,就是指定要獲取的構造方法的引數型別。
當我們獲取了構造方法後,可以通過構造方法物件的newInstance()
建立相應的類物件,引數即為類物件建立時需要傳遞的引數值。
T newInstance(Object... initargs)
測試方法:
/**
* 測試通過反射獲取構造方法
*/
@Test
public void testGetConstructor() throws Exception {
Class<Student> studentClass = Student.class;
//獲取構造方法物件
Constructor<Student> constructor = studentClass.getConstructor(String.class, LocalDate.class);
System.out.println(constructor);
//構造學生物件
Student student = constructor.newInstance("張三", LocalDate.of(2000, 12, 2));
System.out.println(student);
}
結果:
3.4 獲取成員方法
當建立了一個Class物件後,我們可以使用以下方法獲取成員方法:
方法 宣告 | 方法 解釋 |
---|---|
Method getMethod(String name, Class<?>... parameterTypes) | 獲取指定方法名稱和引數型別的公共成員方法。 |
Method[] getMethods() | 獲取所有的公共成員方法。 |
Method getDeclaredMethod(String name, Class<?>... parameterTypes) | 獲取指定方法名稱和引數型別的成員方法,不再限制訪問修飾符。 |
Method[] getDeclaredMethods() | 獲取所有的公共成員方法,不再限制訪問修飾符。 |
當獲取方法後,可以通過invoke()
執行該方法。
Object invoke(Object obj, Object... args)
可以通過getName()
獲取方法名稱。