java框架的核心:反射机制详解

假设我们有一个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(){
        
    }
}

    下面我来写一个ObjectUtil类,该类的私有变量和构造函数如下

    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()。

        除了获取name和type,field类还有许多其他的方法,比如.getGenericType()返回的是getType()的string类型,

toGenericString()返回的是该字段笼统的概括 如:private java.lang.String com.text.Dog.name

getModifiers()返回的是该属性的范围的int值:public<==>1,private<==>2

set(object,objectVal)该方法的用途比较有限,要求属性是public类型的属性才能用,但大部分对象类是不会把属性设置成public的。它的第一个参数是类中的某个属性,第二个参数是该属性的值,相当于在类中中直接定义其他类的属性值:

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

 二.  Method类

    下面我们通过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(){
        
    }
}

















转载于:https://my.oschina.net/u/2323537/blog/385955

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值