java框架的核心:反射機制詳解

假設咱們有一個Master類,下面我開始對該類進行反射機制的研究:java

class Master{
    private String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Master(String name,int age){
        this.name=name;
        this.age=age;
    }
    public Master(){
        
    }
}

    下面我來寫一個ObjectUtil類,該類的私有變量和構造函數以下spring

    private Map<String, Class> map=null;//用來存放待處理類中存在的屬性以及屬性類型
    private static Object object;//咱們要處理的類
    public ObjectUtil(Object object){
        this.object=object;
    }

一. Field類
框架

Field在jdk中的描述:提供有關類或接口的單個字段的信息,能夠對它的動態訪問權限。所以,咱們能夠根據field對象獲得object中的屬性名,屬性類型和方法等信息。函數

    /*
     * 獲取object的屬性名
     * */
     public  Map<String, Class> getNames(){
        Field fields[]=object.getClass().getDeclaredFields();
        map=new HashMap<String, Class>();
        for (int i = 0; i < fields.length; i++) {
            map.put(fields[i].getName(), fields[i].getType());
        }
        return map;
    }

上面代碼展現瞭如何經過Field獲取對象中的屬性名和該屬性的類型,對應的方法分別是 field.getName()和field.getType()。this

        除了獲取name和type,field類還有許多其餘的方法,好比.getGenericType()返回的是getType()的string類型,spa

toGenericString()返回的是該字段籠統的歸納 如:private java.lang.String com.text.Dog.namecode

getModifiers()返回的是該屬性的範圍的int值:public<==>1,private<==>2對象

set(object,objectVal)該方法的用途比較有限,要求屬性是public類型的屬性才能用,但大部分對象類是不會把屬性設置成public的。它的第一個參數是類中的某個屬性,第二個參數是該屬性的值,至關於在類中中直接定義其餘類的屬性值:接口

Master master=new Master();
         master.id=12;

 二.  Method類get

    下面咱們經過class類獲取對象屬性的值,因爲對象屬性通常都是私有的,想獲取屬性的值必須執行get屬性方法,因此咱們須要經過構造get方法名來得到值

/*
     * 根據object的屬性名某對象該屬性的屬性值
     * */
    public  Object getValue(String name){
        if(map==null){
            this.getNames();
        }
        String methodName="get"+name.substring(0,1).toUpperCase()+name.substring(1,name.length());
        Method method;
        Class class1=map.get(name);
        Object valObject=null;
        try {
            method=object.getClass().getDeclaredMethod(methodName, new Class[]{});
            valObject=method.invoke(object,new Object[]{});
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
         return valObject;
    }

    從上述代碼中能夠看出,

object.getClass().getMethod(methodName, new Class[]{});

    能夠構造出一個方法實例,方法名是methodName,方法中傳入的參數類型是new Class[]{}


valObject=method.invoke(object,new Object[]{});

    能夠獲取object對象在執行該方法的時候返回的對象,new object[]{}是對應參數,數量必須與上面的new class的數量相同否則報錯,若是該方法是void方法,則返回null。

    若是咱們想讓該方法返回string類型的值,只需把valObject強轉爲string便可,其它類型也相仿。


valObject=class1.newInstance();

    該方法須要注意的是,假設咱們要獲取的屬性真的是一個自定義的對象(好比在master中定義了一個dog類),這個對象的構造函數中不能有參數,這就是spring框架規定若是bean中非要寫一個帶參數的構造函數的話,必須重寫一遍不帶參數的構造函數 的緣由。  

    get方法完成,咱們來寫最難的set方法:

/*
     * set方法
     * */
    public  ObjectUtil setValue(String name,Object valueObject){
        String setMethod="set"+name.substring(0,1).toUpperCase()+name.substring(1,name.length());
        if(map==null){
            map=this.getNames();
        }
        Class class1=map.get(name);
        Method method;
        try {
            method=object.getClass().getDeclaredMethod(setMethod, class1);
            method.invoke(object, valueObject);
            
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return new ObjectUtil(object);
    }

這裏返回ObjectUtil的緣由應該很容易理解了,這樣就能夠鏈式set值了,好比

        ObjectUtil util=new ObjectUtil(new Master("xiaoli", 13));
         util.setValue("age", 1).setValue("name", "xxx");

自此set、get方法完成,所有代碼總結以下

package com.text;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.KeyStore.Entry;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class ObjectUtil {
    private Map<String, Class> map=null;
    private static Object object;
    public ObjectUtil(Object object){
        this.object=object;
    }
    public static void main(String[] args) {
         ObjectUtil util=new ObjectUtil(new Master("xiaoli", 13));
         util.setValue("age", 1).setValue("name", "xxx");
         
    }
    /*
     * 獲取object的屬性名
     * */
     public  Map<String, Class> getNames(){
        Field fields[]=object.getClass().getDeclaredFields();
        map=new HashMap<String, Class>();
        for (int i = 0; i < fields.length; i++) {
            map.put(fields[i].getName(), fields[i].getType());
        }
        return map;
    }
    /*
     * 根據object的屬性名某對象該屬性的屬性值
     * */
    public  Object getValue(String name){
        if(map==null){
            this.getNames();
        }
        String methodName="get"+name.substring(0,1).toUpperCase()+name.substring(1,name.length());
        Method method;
        Class class1=map.get(name);
        Object valObject=null;
        try {
            method=object.getClass().getDeclaredMethod(methodName, new Class[]{});
            valObject=method.invoke(object,new Object[]{});
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
         return valObject;
    }
    /*
     * set方法
     * */
    public  ObjectUtil setValue(String name,Object valueObject){
        String setMethod="set"+name.substring(0,1).toUpperCase()+name.substring(1,name.length());
        if(map==null){
            map=this.getNames();
        }
        Class class1=map.get(name);
        Method method;
        try {
            method=object.getClass().getDeclaredMethod(setMethod, class1);
            method.invoke(object, valueObject);
            
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return new ObjectUtil(object);
    }
}
class Dog{
    private String name;
    private int id;
    private Master master;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public Dog(String name,int id,Master master){
        this.name=name;
        this.id=id;
        this.master=master;
    }
    public Dog(){
        System.out.println("被執行");
    }
    public Master getMaster() {
        return master;
    }
    public void setMaster(Master master) {
        this.master = master;
    }
}
class Master{
    private String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Master(String name,int age){
        this.name=name;
        this.age=age;
    }
    public Master(){
        
    }
}
相關文章
相關標籤/搜索