溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

JDK中的反射有什么作用

發(fā)布時(shí)間:2021-07-07 16:37:22 來(lái)源:億速云 閱讀:121 作者:chen 欄目:大數(shù)據(jù)

這篇文章主要介紹“JDK中的反射有什么作用”,在日常操作中,相信很多人在JDK中的反射有什么作用問題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”JDK中的反射有什么作用”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

在運(yùn)行狀態(tài)中,我們可以根據(jù)“類的部分已知的信息”來(lái)還原“類的全部的信息”。

類的部分已知的信息:

  • 類名

  • 類的對(duì)象

類的全部信息

  • 屬性

  • 方法

  • 繼承關(guān)系

  • Annotation注解

根據(jù)類名構(gòu)造類

代碼示例

User類

public class User implements Serializable{
    private static final long serialVersionUID = 1510634274152200118L;
    
    private int id;
    private String passWord;
    
    public User() {
        System.out.println("Create user... ");
    }
    
    public User(int id, String passWord) {
        this.id = id;
        this.passWord = passWord;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getPassWord() {
        return passWord;
    }
    public void setPassWord(String passWord) {
        this.passWord = passWord;
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", passWord=" + passWord + "]";
    }
}

根據(jù)類名,構(gòu)造類的代碼:

@Test
public void testReflection() throws Exception {
    Class<?> clazz = Class.forName("test.User");
    User user = (User) clazz.newInstance();
    System.out.println("user = " + user);
}

輸出:

Create user... 
user = User [id=0, passWord=null]

獲取 class 對(duì)象

@Test
public void testClazz() throws Exception {
    Class<?> clazz1 = Class.forName("test.User");
    Class clazz2 = User.class;
    Class clazz3 = new User().getClass();
    System.out.println("clazz1: " + clazz1);
    System.out.println("clazz2: " + clazz2);
    System.out.println("clazz3: " + clazz3);
}

輸出:

Create user... 
clazz1: class test.User
clazz2: class test.User
clazz3: class test.User

class 的 API

  • 構(gòu)造函數(shù)

  • 成員方法

  • 成員變量

  • 類的其它信息(如注解、包名、類名、繼承關(guān)系等等)

構(gòu)造函數(shù)

// 獲取“參數(shù)是parameterTypes”的public的構(gòu)造函數(shù)
public Constructor    getConstructor(Class[] parameterTypes)
// 獲取全部的public的構(gòu)造函數(shù)
public Constructor[]    getConstructors()
// 獲取“參數(shù)是parameterTypes”的,并且是類自身聲明的構(gòu)造函數(shù),包含public、protected和private方法。
public Constructor    getDeclaredConstructor(Class[] parameterTypes)
// 獲取類自身聲明的全部的構(gòu)造函數(shù),包含public、protected和private方法。
public Constructor[]    getDeclaredConstructors()
// 如果這個(gè)類是“其它類的構(gòu)造函數(shù)中的內(nèi)部類”,調(diào)用getEnclosingConstructor()就是這個(gè)類所在的構(gòu)造函數(shù);若不存在,返回null。
public Constructor    getEnclosingConstructor()

測(cè)試:

@Test
public void testConstructor() throws Exception {
    Class<?> clazz = Class.forName("test.User");
    Constructor<?> constructor = clazz.getDeclaredConstructor(null);
    Object object1 = constructor.newInstance();
    System.out.println(object1);
    
    Constructor<?> constructor2 = clazz.getDeclaredConstructor(new Class[] {int.class, String.class});
    Object object2 = constructor2.newInstance(1, "123456");
    System.out.println(object2);
}

輸出:

Create user... 
User [id=0, passWord=null]
User [id=1, passWord=123456]

可以調(diào)用默認(rèn)的構(gòu)造函數(shù),也可以通過(guò)

clazz.getDeclaredConstructor(new Class[] {int.class, String.class})

來(lái)調(diào)用User的含參構(gòu)造函數(shù)

public User(int id, String passWord) {
    this.id = id;
    this.passWord = passWord;
}

成員方法

// 獲取“名稱是name,參數(shù)是parameterTypes”的public的函數(shù)(包括從基類繼承的、從接口實(shí)現(xiàn)的所有public函數(shù))
public Method    getMethod(String name, Class[] parameterTypes)
// 獲取全部的public的函數(shù)(包括從基類繼承的、從接口實(shí)現(xiàn)的所有public函數(shù))
public Method[]    getMethods()
// 獲取“名稱是name,參數(shù)是parameterTypes”,并且是類自身聲明的函數(shù),包含public、protected和private方法。
public Method    getDeclaredMethod(String name, Class[] parameterTypes)
// 獲取全部的類自身聲明的函數(shù),包含public、protected和private方法。
public Method[]    getDeclaredMethods()
// 如果這個(gè)類是“其它類中某個(gè)方法的內(nèi)部類”,調(diào)用getEnclosingMethod()就是這個(gè)類所在的方法;若不存在,返回null。
public Method    getEnclosingMethod()

可以判斷類中是否含有某個(gè)方法,也可以調(diào)用類中的任何一個(gè)方法(包括私有方法)。

@Test
public void testMethod() throws Exception {
    Class<?> clazz = Class.forName("test.User");
    
    Method[] declaredMethods = clazz.getDeclaredMethods();
    for (Method method : declaredMethods) {
        System.out.println(method);
    }
    System.out.println();
    
    Method printInfo = clazz.getDeclaredMethod("printInfo", new Class[]{});
    User user = (User) clazz.newInstance();
    printInfo.invoke(user, null);
}

輸出:

Create user... 
public java.lang.String test.User.toString()
public int test.User.getId()
public void test.User.printInfo()
public void test.User.setId(int)
public void test.User.setPassWord(java.lang.String)
public java.lang.String test.User.getPassWord()
User [id=0, passWord=null]

成員變量

// 獲取“名稱是name”的public的成員變量(包括從基類繼承的、從接口實(shí)現(xiàn)的所有public成員變量)
public Field    getField(String name)
// 獲取全部的public成員變量(包括從基類繼承的、從接口實(shí)現(xiàn)的所有public成員變量)
public Field[]    getFields()
// 獲取“名稱是name”,并且是類自身聲明的成員變量,包含public、protected和private成員變量。
public Field    getDeclaredField(String name)
// 獲取全部的類自身聲明的成員變量,包含public、protected和private成員變量。
public Field[]    getDeclaredFields()
@Test
public void testField() throws Exception {
    Class<?> clazz = Class.forName("test.User");
    
    Field[] fields = clazz.getDeclaredFields();
    for (Field field : fields) {
        System.out.println(field);
    }
    
    // 創(chuàng)建并通過(guò)反射,修改一個(gè) private 變量 id
    User user = (User) clazz.newInstance();
    Field field = clazz.getDeclaredField("id");
    field.setAccessible(true);
    field.set(user, 123);
    user.printInfo();
}

輸出:

private static final long test.User.serialVersionUID
private int test.User.id
private java.lang.String test.User.passWord
Create user... 
User [id=123, passWord=null]

我們可以看到,User中對(duì)于id的定義:

private int id;

而在測(cè)試用例中,可以獲取對(duì)象中私有的id變量,并直接修改內(nèi)容,最終輸出的id=123。

類的其它信息

注解

// 獲取類的"annotationClass"類型的注解 (包括從基類繼承的、從接口實(shí)現(xiàn)的所有public成員變量)
public Annotation<A>    getAnnotation(Class annotationClass)
// 獲取類的全部注解 (包括從基類繼承的、從接口實(shí)現(xiàn)的所有public成員變量)
public Annotation[]    getAnnotations()
// 獲取類自身聲明的全部注解 (包含public、protected和private成員變量)
public Annotation[]    getDeclaredAnnotations()

“父類”和“接口”相關(guān)的API

// 獲取實(shí)現(xiàn)的全部接口
public Type[]    getGenericInterfaces()
// 獲取父類
public Type    getGenericSuperclass()

到此,關(guān)于“JDK中的反射有什么作用”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

jdk
AI