java反射--Field

本文详细介绍了如何利用Java反射API在不同实体类间进行属性值的复制,包括如何通过getFields()和getDeclaredFields()方法获取类的属性,并通过setAccessible()方法设置属性的访问权限,最终实现属性的赋值操作。


反射中有个属性类Field,其提供关于属性的操作,下面通过一个实例来展示Field的运用!


首先:


需要弄清楚 getFields()和getDeclaredFields()获取属性字段的区别:


getFields():获取该类中的public属性,包括从父类中继承的public属性字段。仅限public修饰的属性。


getDeclaredFields():获取该类中的所有属性,包括public,protected,private,【默认】修饰的属性。但是不包括父类的所有属性。


LeftEntity le = new LeftEntity();

Class clazz = le.getClass();

Field[] fields = clazz.getDeclaredFields();

// 该属性的修饰符
int modifiers  = field.getModifiers();

下面是modifiers的值分别对应的修饰符:

0:默认的
1:public
2:private
4:protected



实例代码Field  


下面上实例代码【实例目的:把RightEntity中属性的值赋给LeftEntity的相同属性】:


首先,实体类[由于只是测试反射,所以实体类中的属性注释就没写了,没有实际意义]:


package com.main.src.entity;

import java.util.Date;

public class RightEntity {

    public String name       = null;

    public String pass       = null;

    public int    age        = 0;

    public Date   createDate = null;

    /************区分字段******************/

    public String constrict  = null;

    public String province   = null;

    public RightEntity() {
        this.name = "张三";
        this.pass = "123456";
        this.age = 20;
        this.createDate = new Date();
        this.constrict = "西湖区";
        this.province = "浙江省";
    }

    public String getName() {
        return name;
    }

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

    public String getPass() {
        return pass;
    }

    public void setPass(String pass) {
        this.pass = pass;
    }

    public int getAge() {
        return age;
    }

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

    public Date getCreateDate() {
        return createDate;
    }

    public void setCreateDate(Date createDate) {
        this.createDate = createDate;
    }

    public String getConstrict() {
        return constrict;
    }

    public void setConstrict(String constrict) {
        this.constrict = constrict;
    }

    public String getProvince() {
        return province;
    }

    public void setProvince(String province) {
        this.province = province;
    }

}



package com.main.src.entity;

import java.util.Date;

public class LeftEntity {

    private String name       = null;

    public String  pass       = null;

    int            age        = 0;

    protected Date createDate = null;

    /************区分字段******************/

    public String  country    = null;

    public String  city       = null;

    public String getName() {
        return name;
    }

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

    public String getPass() {
        return pass;
    }

    public void setPass(String pass) {
        this.pass = pass;
    }

    public int getAge() {
        return age;
    }

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

    public Date getCreateDate() {
        return createDate;
    }

    public void setCreateDate(Date createDate) {
        this.createDate = createDate;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

}



实现类:

package com.main.src.businessImpl;

import java.lang.reflect.Field;

public class BizImpl {

    /**
     * 通过泛型定义的方法,给两个类的相同属性赋值
     * 
     * @param <T>
     * @param <K>
     * @param t
     * @param k
     * @return
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     */
    public static <T, K> T entityValueChange(T t, K k) throws IllegalArgumentException,
                                                      IllegalAccessException {

        // 获取类加载对象Class
        Class claT = t.getClass();

        Class claK = k.getClass();

        // 获取该类中所有属性
        Field[] fieldTs = claT.getDeclaredFields();

        Field[] fieldKs = claK.getDeclaredFields();

        for (Field fieldt : fieldTs) {
            // 当该属性修饰符不是public的场合,需要给该属性添加可访问标识
            if (fieldt.getModifiers() != 1) {
                fieldt.setAccessible(true);
            }

            for (Field fieldk : fieldKs) {

                // 当属性名称和类型都相同的时候才赋值
                if (fieldt.getName().equals(fieldk.getName())
                    && fieldt.getType() == fieldk.getType()) {

                    if (fieldk.getModifiers() != 1) {
                        fieldk.setAccessible(true);
                    }

                    // 赋值
                    fieldt.set(t, fieldk.get(k));
                }

            }

        }
        // 返回值
        return t;
    }

}


测试执行类:

    /**
     * 
     * @param args
     * @throws IllegalAccessException 
     * @throws IllegalArgumentException 
     * @throws NoSuchFieldException 
     * @throws SecurityException 
     * @throws IllegalAccessException 
     * @throws IllegalArgumentException 
     */
    public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException {

        // 有值的实体类
        RightEntity re = new RightEntity();
        // 待赋值实体类
        LeftEntity le = new LeftEntity();

        // 给实体相同属性赋值
        le = BizImpl.entityValueChange(le, re);

        // 在这里获取类加载对象Class的时候,还可以用这种方法获取【Class clazz = LeftEntity.class;】
        Class clazz = le.getClass();

        // 获取该类所有属性并打印值
        Field[] fields = clazz.getDeclaredFields();

        for (Field field : fields) {
            // 当该属性修饰符不是public的场合,需要给该属性添加可访问标识
            if (field.getModifiers() != 1) {
                field.setAccessible(true);
            }
            System.out.println(field.getName() + "=" + field.get(le));
        }

    }


程序执行结果:

name=张三
pass=123456
age=20
createDate=Wed Oct 28 17:47:28 CST 2015
country=null
city=null


----反射赋值(此可以用于解析socket报文体,DecodeMessage用):

String body = "1&2&3&4&5&6&7&8&9&10&11&12";

String[] fieldValues = StringUtils.split(body, "&");

Field[] fields = ClassA.class.getDeclaredFields();

Object obj = new ClassA();

for (int i = 0; i < fieldValues.length; i++) {
	fields[i].setAccessible(true);
	fields[i].set(obj, fieldValues[i]);
}

System.out.println(obj);




对这个感兴趣的朋友可以执行看看,最好是自己写一个,看着是简单的例子,不写完全发现不了其中隐藏的细节问题,这里就不一一说明了!


欢迎指出不足的地方,一起多探讨!!!!




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值