1. 程式人生 > >java反射的介紹以及程式碼操作

java反射的介紹以及程式碼操作

java反射在小編眼裡類似於一個遠端操作器,在訪問、檢測、修改上更加便利而且是通過類似於不干涉所需操作物件進行相關操作。

反射功能在:java.lang.reflect 包中

java反射的實現首先是基於Class物件,在進行相應操作時首先根據所需操作類建立一個物件

Class 物件名=類物件名.getClass();

反射體現主要分為三個方法

1.訪問構造方法(Constructor類相關方法實現)

2.訪問成員變數(Field類相關方法實現)

3.訪問方法(Method類相關方法實現)

便於理解以下是一個程式碼例項來介紹相應功能

首先我們編寫一個普通類

public class Test1 {
    int a;
    public float b;
    protected  boolean c;
    private String d;  //此處為了便利操作各種物件都加上進行具體操作
    public Test1(){
    }  //定義一個無參構造方法
    public Test1(int a,float b){
        this.a=a;
        this.b=b;
    }
    public int setA() {
        System.out.println("返回a的三次方");
        return (a*a*a);
    }   //隨意定義幾個方法之後可能會用到驗證
    public float setB() {
        System.out.println("返回a與b的乘積");
        return ((float)a*b);
    }

    public boolean isC() {
        System.out.println("如果a,b乘積不為0則輸出true");
        if (setB()!=0){
            return true;
        }
        else {
            return false;
        }
    }
    public void getD() {
     System.out.println("操作成功");
    }
}

然後編寫一個類實現反射對其進行相關操作

import java.lang.reflect.*;
public class Test2 {
    public static void main(String[] args) {

        Test1 test1=new Test1(5,2.12f);  //先建立類物件
        Class test=test1.getClass();      //建立Class物件實現對類的一些操作

        Constructor[]a=test.getConstructors(); //以一個Constructor陣列儲存類物件的構造方法
        System.out.println("該類中有"+a.length+"個構造方法");  //讀取一下陣列長度瞭解一下其中有多少個方法

        for (int i = 0; i < a.length; i++) {
            Constructor p=a[i];   //每次迴圈以一個Constructor物件獲取Constructor陣列a中元素然後以p進行操作
            System.out.println("第"+(i+1)+"個構造方法中是否有可變數量引數");
            System.out.println(p.isVarArgs());
            Class b[]=p.getParameterTypes();     //以Class陣列儲存相應建構函式的引數型別
            for (int j = 0; j < b.length; j++) {
                System.out.println("第"+(i+1)+"個函式的第"+(j+1)+"引數型別為"+b[j]);
            }
        }
        System.out.println("a的值為"+test1.a);
        System.out.println("b的值為"+test1.b);
        Field []element=test.getDeclaredFields();  //定義Field物件獲取所有成員變數
        for (int i = 0; i < element.length; i++) {
            Field d=element[i];  //同上操作新建物件來獲取陣列物件進行操作,迴圈遍歷每個成員變數
            Class q=d.getType();  //定義一個q來儲存獲取的成員變數的型別以便做判斷
            System.out.println("第"+(i+1)+"個引數名為"+d.getName());
            try{
                if (q.equals(int.class)){
                    d.setInt(test1,9);  該方法實現對類物件裡該型別成員變數值的修改
                }  //判斷成員型別然後進行成員變數修改
                else {
                    d.setFloat(test1,3.14f);
                }  //這邊只對兩個變數進行了判斷修改同時還可以給為賦值物件賦值
            }catch (Exception e){

            }
        }
        System.out.println("通過遠端修改後");
        System.out.println("a的值為"+test1.a);
        System.out.println("b的值為"+test1.b);
        
    }
}

這邊程式碼裡省略了訪問方法的一些具體做法因為在實現上與上述差不多所以這邊直接做介紹

同樣一般首先獲取類中所有方法 Method[] 物件名=類物件名.getDeclaredMethods();

方法介紹:

getName();   //獲取方法名

getParameterTypes();   //以Class陣列獲取方法引數型別

getReturnType();         //獲取方法返回值型別

invoke(類物件名,方法引數);   //該操作可以實現方法的執行