Java8替代传统反射动态获取成员变量值的一个示例
业务背景
新人注册发优惠券 要发送的券的信息以json的格式配置 如下所示
{
"count":2 #发放2张
"days":"3,7" #有效期天数 一个有效期天数是3天 一个是7天
"price":"50" #优惠券面额 2个券的面额都是50元
}
有一个CouponConfig
对象对应的是上述Json配置
public class CouponConfig {
/**
* 发放张数
*/
private int count;
/**
* 有效期
*/
private String days;
/**
* 优惠券面额
*/
private String price;
现在想得到一个CouponInfo
列表 如发送2张 即要得到一个size=2的couponInfo列表 每个CouponInfo即对应一种发送券信息 于是需要解析原始的days,price
静态的方法 即每个成员变量都有一份
public int getDays(int i){
if(this.days.indexOf(",")==-1){ //取值相同
return Integer.parseInt(days);
}else{
return Integer.parseInt(days.split(",")[i]);
}
}
public int getPrice(int i){
if(this.price.indexOf(",")==-1){ // 取值相同
return Integer.parseInt(price);
}else{
return Integer.parseInt(price.split(",")[i]);
}
}
调用示例
for (int i = 0; i < config.getCount(); i++) {
System.out.println(config.getDays(i));
System.out.println(config.getPrice(i));
}
缺点
代码冗余 需写多份
反射
可以通过传统反射来动态获取成员变量做到只写一份 如下所示
public int getEachValue(int i, String fieldName){
try {
String str = (String) ReflectionUtils.invokeMethod(this.getClass().getMethod("get"+ capitalise(fieldName)), this);
if(str.indexOf(",")==-1){
return Integer.parseInt(str);
}else{
return Integer.parseInt(str.split(",")[i]);
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
return -1;
}
此时调用示例
for (int i = 0; i < config.getCount(); i++) {
System.out.println(config.getEachValue(i, "days"));
System.out.println(config.getEachValue(i, "price"));
}
缺点
对重构不友好 如修改了days-->expireDays 并不会有编译提示
Java8
使用Java8来代替传统反射
public int getEachValue(int i, Supplier<String> supplier){
if(supplier.get().indexOf(",")==-1){
return Integer.parseInt(supplier.get());
}else{
return Integer.parseInt(supplier.get().split(",")[i]);
}
}
调用示例
for (int i = 0; i < config.getCount(); i++) {
System.out.println(config.getEachValue(i,config::getDays));
System.out.println(config.getEachValue(i,config::getPrice));
}
此时若修改了变量名称 编译失败
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。