Java8替代傳統反射動態獲取成員變量值的一個示例json
業務背景segmentfault
新人註冊發優惠券 要發送的券的信息以json的格式配置 以下所示api
{ "count":2 #發放2張 "days":"3,7" #有效期天數 一個有效期天數是3天 一個是7天 "price":"50" #優惠券面額 2個券的面額都是50元 }
有一個CouponConfig
對象對應的是上述Json配置this
public class CouponConfig { /** * 發放張數 */ private int count; /** * 有效期 */ private String days; /** * 優惠券面額 */ private String price;
如今想獲得一個CouponInfo
列表 如發送2張 即要獲得一個size=2的couponInfo列表 每一個CouponInfo即對應一種發送券信息 因而須要解析原始的days,pricecode
靜態的方法 即每一個成員變量都有一份對象
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)); }
代碼冗餘 需寫多份get
能夠經過傳統反射來動態獲取成員變量作到只寫一份 以下所示it
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; }
此時調用示例io
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來代替傳統反射
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)); }
此時若修改了變量名稱 編譯失敗