完全搞定,Java中反射的應用(取得類的結構) 一、基本概念 二、取得所實現的全部接口 三、取得父類 四、取得全部構造方法 五、取得全部方法 六、取得全部屬性

框架:半成品軟件,可以在框架的基礎上進行軟件開發,簡化編碼

反射:將類的各個組成部分封裝爲其他對象,這就是反射機制

好處:
    * 可以在程序運行過程中,操作這些對象。
    * 可以解耦,提高程序的可擴展性。

一、基本概念

在反射機制中,還可以通過反射得到一個類的完整結構,這就需要使用 java.lang.reflect 包中的以下幾個類:

Constructor:表示類中的構造方法
Field:表示類中的屬性
Method:表示類中的方法

這三個類都是 AccessibleObject 類的子類:

interface China{
    public static final String NATIONAL = "China";
    public static final String AUTHOR = "Java";
    public void sayChina();//定義無參的抽象方法
    public String sayHello(String name,int age);//定義有參的抽象方法
}
class Person implements China{
    private String name;
    private int age;
    public Person(){
    }
    public Person(String name){//聲明有一個參數的構造方法
        this.name = name;
    }
    public Person(String name,int age){
        this(name);
        this.setAge(age);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public void sayChina() {
        System.out.println("作者:" + AUTHOR + ",國籍:" + NATIONAL);
    }

    @Override
    public String sayHello(String name, int age) {
        return name + "你好!我今年" + age + "歲了!";
    }
}

二、取得所實現的全部接口

要取得一個類所實現的全部接口,必須使用 Class 類中的 getInterfaces() 方法,該方法定義:

public Class[] getInterfaces()

getInterfaces() 方法返回一個 Class 類的對象數組,之後直接利用 Class 類中的 getName() 方法輸出即可。

public class Root{
    public static void main(String[] args) {
        Class<?> c1 = null;//聲明 Class對象
        try{
            c1 = Class.forName("Person");
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        }
        Class<?> c[] = c1.getInterfaces();//取得實現的全部接口
        for (int i=0;i<c.length;i++){
            System.out.println("實現的接口名稱:" + c[i].getName());//輸出接口名稱
        }
    }
}

因爲接口是類的特殊形式,而且一個類可以實現多個接口,所以此時以 Class 數組的形式將全部的接口對象返回,並利用循環的方式將內容依次輸出

三、取得父類

一個類可以實現多個接口,但是隻能繼承一個父類,所以要想取得一個類的父類,可以直接使用 Class 類中的 getSuperclass() 方法,該方法定義:

public Class<? super T> getSuperclass()

getSuperclass() 方法返回的是 Class 實例,和之前得到的接口一樣,可以通過 getName() 方法取得名稱。

public class Test{
    public static void main(String[] args) {
        Class<?> c1 = null;
        try {
            c1 = Class.forName("Person");
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        }
        Class<?> c2 = c1.getSuperclass();//取得父類信息
        System.out.println("父類名稱:" + c2.getName());
    }
}

Person 類在編寫時沒有明確地繼承一個父類,所以默認繼承 Object 類

四、取得全部構造方法

要取得一個類中的全部構造方法,必須使用 Class 類中的 getConstructors() 方法。

1.取得 Person 類的全部構造方法

import java.lang.reflect.Constructor;

public class Test{
    public static void main(String[] args) {
        Class<?> c1 = null;
        try {
            c1 = Class.forName("Person");
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        }
        Constructor<?> con[] = c1.getConstructors();//得到全部構造方法
        for (int i=0;i<con.length;i++){
            System.out.println("構造方法:" + con[i]);
        }
    }
}

2.取得一個類的全部構造方法

import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;

public class Test{
    public static void main(String[] args) {
        Class<?> c1 = null;
        try {
            c1 = Class.forName("Person");
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        }
        Constructor<?> con[] = c1.getConstructors();//得到全部構造方法
        for (int i=0;i<con.length;i++){
            Class<?> p[] = con[i].getParameterTypes();//列出構造中的參數類型
            System.out.print("構造方法:");
            int mo = con[i].getModifiers();//取出權限
            System.out.print(Modifier.toString(mo) + " ");//還原權限
            System.out.print(con[i].getName());//輸出構造方法名稱
            System.out.print("(");
            for (int j=0;j<p.length;j++){
                System.out.print(p[j].getName() + " arg" + i);
                if (j<p.length-1){//打印參數類型,判斷是否要輸出“,”
                    System.out.print(",");
                }
            }
            System.out.println("){}");
        }
    }
}

五、取得全部方法

要取得一個類中的全部方法,可以使用 Class 類中的 getMethods() 方法,該方法返回一個 Method 類的對象數組。該方法的常用方法:

取得一個類的全部方法定義:

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class Test{
    public static void main(String[] args) {
        Class<?> c1 = null;
        try {
            c1 = Class.forName("Person");
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        }
        Method m[] = c1.getMethods();//取得全部的方法
        for (int i=0;i<m.length;i++){
            Class<?> r = m[i].getReturnType();//取出方法的返回值類型
            Class<?> p[] = m[i].getParameterTypes();//得到全部的參數類型
            int xx = m[i].getModifiers();//得到方法的修飾符
            System.out.print(Modifier.toString(xx) + " ");//還原修飾符
            System.out.print(r.getName() + " ");//得到方法名稱
            System.out.print(m[i].getName());//取得方法名稱
            System.out.print("(");
            for (int x=0;x<p.length;x++){
                System.out.print(p[x].getName() + " " + "arg" + x);//輸出參數
                if (x<p.length-1){
                    System.out.print(",");//判斷是否輸出","
                }
            }
            Class<?> ex[] = m[i].getExceptionTypes();//得到全部的異常拋出
            if (ex.length>0){
                System.out.print(") throws ");//輸出“) throws”
            }else {
                System.out.print(")");
            }
            for (int j=0;j<ex.length;j++){
                System.out.print(ex[j].getName());//輸出異常信息
                if (j<ex.length-1){
                    System.out.print(",");
                }
            }
            System.out.println();
        }
    }
}

開發工具就是利用了反射的原理

六、取得全部屬性

在反射操作中也同樣可以取得一個類中的全部屬性,有兩種不同的操作:

得到實現的接口或父類中的公共屬性:public Field[] getFields() throws SecurityException
得到本類中的全部屬性:public Field[] getDeclareDeclaredFields() throws SecurityException

上述方法返回的都是 Field 的數組,每一個 Field 對象表示類中的一個屬性,而要想取得屬性的進一步信息,需要使用:

取得 Person 類中的屬性

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class Test{
    public static void main(String[] args) {
        Class<?> c1 = null;
        try {
            c1 = Class.forName("Person");
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        }
        {//普通代碼塊
            Field f[] = c1.getDeclaredFields();//取得本類屬性
            for (int i=0;i<f.length;i++){
                Class<?> r = f[i].getType();//取得屬性的類型
                int mo = f[i].getModifiers();//得到修飾符數字
                String priv = Modifier.toString(mo);//取得屬性的修飾符
                System.out.print("本類屬性:");
                System.out.print(priv + " ");//輸出修飾符
                System.out.print(r.getName() + " ");//輸出屬性類型
                System.out.print(f[i].getName());//輸出屬性名稱
                System.out.println(";");//換行
            }
        }
        System.out.println("===========================");
        {
            Field f[] = c1.getFields();//取得父類公共屬性
            for (int i=0;i<f.length;i++){
                Class<?> r = f[i].getType();//取得屬性的類型
                int mo = f[i].getModifiers();//取得修飾符數字
                String priv = Modifier.toString(mo);//取得屬性修飾符
                System.out.print("公共屬性:");
                System.out.print(priv + " ");//輸出修飾符
                System.out.print(r.getName() + " ");//輸出參數類型
                System.out.print(f[i].getName());//輸出屬性名稱
                System.out.println(";");
            }
        }
    }
}

作者:南淮北安
鏈接:https://juejin.cn/post/6923479418119651342
來源:掘金

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