利用反射和标签自动解析游戏配置

一、遇到麻烦

  1. 在游戏里解析策划配的配置文件(通过程序解析excel后得到的json格式数据文件)过程中,要将每个配置文件与JavaBean实体类的属性一一对应,还要将数据类型转换成与之相对应才行,然后再一个个的手动setXxx进去,当配置的字段越来越来多,解析类就会跟着变得复杂难看。
  2. 所以就想能不能只负责定义属性,至于赋值工作自动完成?
  3. 这样,自然就得用到Java的反射机制和自定义标签这两项技术。

二、具体解决方案

  1. 首先准备一个自定义标签的类,作用在字段上
  2. 通过反射解析类中对应字段上的标签信息
  3. 通过反射将配置值赋值到对应的字段上去

三、参考代码

自定义标签类

package cn.gy.annotion;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 自定义标签类
 * @author: Yang Gao
 * @date: 2017-4-11 下午6:04:22
 * @version: 1.0
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ConfigAnnotion {
    /**
     * 字段名
     */
    String name() default "";
    /**
     * 字段描述
     */
    String desc() default "";

}

配置对应的实体类

package cn.gy.entity;

import cn.gy.annotion.ConfigAnnotion;

/**
 * 测试:配置对应的实体类
 * @author: Yang Gao
 * @date: 2017-4-11 下午6:09:34
 * @version: 1.0
 */
public class People {
    @ConfigAnnotion(name = "c_id", desc = "身份证号")
    private int idCard;
    @ConfigAnnotion(name = "c_name", desc = "姓名")
    private String name;
    @ConfigAnnotion(name = "c_age", desc = "年龄")
    private int age;
    @ConfigAnnotion(name = "c_height", desc = "身高")
    private double height;

    @Override
    public String toString() {
        return new StringBuilder("==========类详细信息==========")
        .append("\n ").append("class=").append(super.toString())
        .append("\n ").append("idCard=").append(getIdCard())
        .append("\n ").append("name=").append(getName())
        .append("\n ").append("age=").append(getAge())
        .append("\n ").append("height=").append(getHeight()).toString();
    }
    public int getIdCard() {
        return idCard;
    }
    public void setIdCard(int idCard) {
        this.idCard = idCard;
    }
    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 double getHeight() {
        return height;
    }
    public void setHeight(double height) {
        this.height = height;
    }
}

具体解析工具类

package cn.gy.utils;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

import cn.gy.annotion.ConfigAnnotion;
import cn.gy.entity.People;

/**
 * 配置自定解析工具类
 * @author: Yang Gao
 * @date: 2017-4-11 下午6:07:47
 * @version: 1.0
 */
public class ConfigAnalysisUtil {
    public static  T autoAnalysis(Class clazz, Map configMap) {
        T result = null;
        try {
            result = clazz.newInstance();
            Field[] fields = clazz.getDeclaredFields();
            for (Field f : fields) {
                ConfigAnnotion annotion = f.getAnnotation(ConfigAnnotion.class);
                if (null == annotion) {
                    continue;
                }
                String cName = annotion.name();// 配置名
                Object cValue = configMap.get(cName);// 配置值
                if (null == cValue) {
                    continue;
                }
                f.setAccessible(true);// 设置访问权限
                f.set(result, cValue);// 赋值
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
    public static void main(String[] args) {
        // 模拟配置数据
        Map configMap = new HashMap();
        configMap.put("c_id", 1234567890);
        configMap.put("c_name", "王大锤");
        configMap.put("c_age", 22);
        configMap.put("c_height", 165.5);
        People p = null;
        try {
            p = autoAnalysis(People.class, configMap);
        } catch (Exception e) {
            System.out.println("自动解析配置错误!!!");
            e.printStackTrace();
        }
        System.out.println(p.toString());
    }
}

运行结果

==========类详细信息==========
 class=cn.gy.entity.People@3c4568f8
 idCard=1234567890
 name=王大锤
 age=22
 height=165.5

你可能感兴趣的:(工作)