Java 类动态添加属性字段

说明:做项目中遇到一种场景,需要根据查询时间段, 获取时间段中中每个月份对应的金额(费用统计)。如截图中的两列

因为列是动态的, 首先想到的就是后天拼接JSON格式字符串, 然后返回到前台, 组装表头及内容。 但是当前系统中easyUI版本为1.2,并不支持 data属性(官方从1.3.2开始支持)。所以只能返回list<T> 格式。

网上一搜相关代码很多, 看客可以自己搜索一下。 我这里记录一下我当时使用场景及用法,已备以后使用。

 

1.需要引用cglib jar包, 我用的版本是2.2

2.建一个实体对象 DynamicBean.java 。主要用来处理对象。

public class DynamicBean {
    private Object object = null; // 动态生成的类

    private BeanMap beanMap = null; // 存放属性名称以及属性的类型

    public DynamicBean() {
        super();
    }

    public DynamicBean(Map propertyMap) {
        this.object = generateBean(propertyMap);
        this.beanMap = BeanMap.create(this.object);
    }

    /**
     * @param propertyMap
     * @return
     */
    private Object generateBean(Map propertyMap) {
        BeanGenerator generator = new BeanGenerator();
        Set keySet = propertyMap.keySet();
        for (Iterator<String> i = keySet.iterator(); i.hasNext();) {
            String key = (String) i.next();
            generator.addProperty(key, (Class) propertyMap.get(key));
        }
        return generator.create();
    }

    /**
     * ��bean���Ը�ֵ
     * @param property ������
     * @param value ֵ
     */
    public void setValue(Object property, Object value) {
        beanMap.put(property, value);
    }

    /**
     * ͨ���������õ�����ֵ
     * @param property ������
     * @return ֵ
     */
    public Object getValue(String property) {
        return beanMap.get(property);
    }

    /**
     * 返回新生成的对象
     * @return
     */
    public Object getObject() {
        return this.object;
    }
}

3. 原来对象, 及需要拼接到对象中的属性字段集合处理方法。

/**
*参数说明:
*  object : 查询结果数组中对象。
*  moneyMap : 为对象对应所有月份数据集合
*  解释:已经查询出一组账单对象集合List<Bill> , 而moneyMap为对象中的一个属性 
*  Map<String,Bigdecimal>, 存放了月份及金额
*/
private Object dynamicClass(Object object, Map<String, BigDecimal> moneyMap) throws Exception {
        // 字段 - 值 集合
        HashMap<String, Object> returnMap = new HashMap<String, Object>();
        // 字段 - 字段类型 集合
        HashMap<String, Object> typeMap = new HashMap<String, Object>();
        // 获取传入类
        Class<? extends Object> type = object.getClass();
        BeanInfo beanInfo = Introspector.getBeanInfo(type);
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        // 获取对象中已存在的数据
        for (int i = 0; i < propertyDescriptors.length; i++) {
            PropertyDescriptor descriptor = propertyDescriptors[i];
            String propertyName = descriptor.getName();
            if (!propertyName.equals("class") && !propertyName.equals("monthMap")) {
                Method readMethod = descriptor.getReadMethod();
                Object result = readMethod.invoke(object, new Object[0]);
                if (result != null) {
                    returnMap.put(propertyName, result);
                } else {
                    String propertyType = descriptor.getPropertyType().toString();
                    if (propertyType.contains("java.math.BigDecimal")) {
                        returnMap.put(propertyName, new BigDecimal(0));
                    } else {
                        returnMap.put(propertyName, "");
                    }
                }
                typeMap.put(propertyName, descriptor.getPropertyType());
            }
        }
        // 获取月份数据, 变为字段属性
        Set<String> monthKeys = moneyMap.keySet();
        for (Iterator<String> it = monthKeys.iterator(); it.hasNext();) {
            String key = (String) it.next();
            // 字段类型
            typeMap.put(key, Class.forName("java.math.BigDecimal"));
            // 字段对应值
            returnMap.put(key, moneyMap.get(key));
        }
        // map转换成实体对象
        DynamicBean bean = new DynamicBean(typeMap);
        // 赋值
        Set<String> keys = typeMap.keySet();
        for (Iterator<String> it = keys.iterator(); it.hasNext();) {
            String key = (String) it.next();
            bean.setValue(key, returnMap.get(key));
        }
        Object obj = bean.getObject();
        return obj;
    }

 

做笔记使用, 说不定以后还会用到。

  • 1
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
1、学生的创建和使用 ○1创建一个Student,包括的域有学号,姓名,性别和年龄,另外增加一个统计学生人数的静态域count; ○2在Student建立构造方法初始化各域的值,并统计学生人数count; ○3创建分别获得各域(学号,姓名,性别和年龄)的public方法,以及分别设置各域(学号,姓名,性别和年龄)值的public方法(即get、set方法);另外还要创建获取静态域count值的get方法; ○4创建public型的toString方法,把该的各域信息(学号,姓名,性别和年龄)组合成一个字符串,如:“141308008,小明,男,20岁”; ○5创建Student的子CollegeStudent(大学生),添加域:专业,静态域count统计大学生人数,建立构造方法并于其中统计大学生人数,并相应添加专业的get、set方法,获取静态域count值的get方法,重写toString方法(把专业信息加进去); ○6创建包含主方法的主,并在主方法测试Student与CollegeStudent:创建Student的两个对象;输出目前的Student对象的人数;分别显示对象的各域信息(学号,姓名,性别和年龄;使用toString方法);修改某个对象的姓名和年龄,然后再显示这个对象的姓名和年龄;比较两个对象的年龄大小,输出年龄较大者的对象的所有域信息(toString方法)。创建CollegeStudent的一个对象;输出目前的CollegeStudent对象的人数;修改对象的姓名、年龄和专业;然后再显示这个对象的全部信息(调用toString方法,或在println方法中直接输出使其自动调用toString方法)。 注:以上中所有域都是private型。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值