一、遇到麻烦
- 在游戏里解析策划配的配置文件(通过程序解析excel后得到的json格式数据文件)过程中,要将每个配置文件与JavaBean实体类的属性一一对应,还要将数据类型转换成与之相对应才行,然后再一个个的手动setXxx进去,当配置的字段越来越来多,解析类就会跟着变得复杂难看。
- 所以就想能不能只负责定义属性,至于赋值工作自动完成?
- 这样,自然就得用到Java的反射机制和自定义标签这两项技术。
二、具体解决方案
- 首先准备一个自定义标签的类,作用在字段上
- 通过反射解析类中对应字段上的标签信息
- 通过反射将配置值赋值到对应的字段上去
三、参考代码
自定义标签类
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> T autoAnalysis(Class<T> clazz, Map<String, Object> 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<String, Object> configMap = new HashMap<String, Object>();
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