反射的概述
反射机制:是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意属性和方法;这种动态获取信息以及动态调用对象方法的功能称为 java 语言的反射机制;
工作原理:当一个字节码文件加载到内存的时候, jvm会对该字节码进行解剖,然后创建一个对象的Class对象,jvm把字节码文件的信息全部都存储到该Class对象中,我们只要获取到Class对象,我们就可以使用该对象设置对象的属性或者调用对象的方法等操作;
使用反射的优势
介于反射机制,在开发过程仲需要对两个实体做比较、或者计算,就可以用到反射来处理;使用反射来实现优势也是很明显,不需要关注实体类以后是否增减字段,可扩展性强且实现代码量小;
业务场景
税收导入需要计算税收额乘以比例之后的合计值作为税收区级纳税额;
备注:两张表大部分字段一致,且类型一致
/**
* 计算税收区级纳税额
* @param taxObj 税收实体
* @param ratioObj 比例实体
* @return
*/
private BigDecimal taxReckon(Object taxObj,Object ratioObj){
// 获取税收所有的属性数组
Field[] field_Tax_Arr = taxObj.getClass().getDeclaredFields();
// 获取税收比例所有的属性数组
Field[] field_Ratio_Arr = ratioObj.getClass().getDeclaredFields();
//计数参数
final BigDecimal[] sumTax = {new BigDecimal("0")};
//循环税收属性
Arrays.stream(field_Tax_Arr).forEach(fieldTax -> {
//开启权限 (实体类字段类型为 private 不设置将获取不到属性)
fieldTax.setAccessible(true);
//判断 税收实体字段类型为BigDecimal
if (fieldTax.getType().isAssignableFrom(BigDecimal.class) ){
//循环比例实体
Field find_one = Arrays.stream(field_Ratio_Arr).filter(field -> {
field.setAccessible(true);
//如果实体字段类型为BigDecimal,且字段名等于税收实体 则返回
return field.getType().isAssignableFrom(BigDecimal.class) && field.getName().equals(fieldTax.getName());
}).findFirst().orElse(null);
//如果返回实体不为空 则进行计算操作
if(find_one != null){
try {
//获取税收额
BigDecimal tax= (BigDecimal) (fieldTax.get(taxObj) == null ? new BigDecimal("0") : fieldTax.get(taxObj));
//获取比例
BigDecimal ratio= (BigDecimal) find_one.get(ratioObj);
//税收合计= sumTax + 税收额*比例
sumTax[0] = sumTax[0].add(tax.multiply(ratio));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
});
//返回合计值
return sumTax[0];
}