问题描述
最近在一个项目上开发的接口与业务方联调时计算参数签名总是对不上,经过排查后定位到原因:
1.父类定义的属性列表,全部为public类型
2.子类中未定义新的属性,所有属性都继承自父类
3.在计算签名时传递的是子类对象,子类对象使用反射方式调用getDeclaredFields()方法无法获取到从父类继承的属性
原因追溯
通过反射方法getDeclaredFields()获取到的仅仅是在类自身中定义的属性,包括public、protected、和private属性,但不包括任何继承的属性(即使继承的属性为public类型也不能获取到)。
举例如下:
// 父类
public class ReflectBase {
public String name;
public int age;
public short sex;
}
// 子类
public class ReflectImpl extends ReflectBase {
// 在子类自身中未定义任何属性
}
ReflectImpl reflect = new ReflectImpl();
Field[] declaredFields = reflect.getClass().getDeclaredFields();
# 在子类中未定义任何属性,输出:0
System.out.println(declaredFields.length);
// 如果在子类自身中定义了属性
public class ReflectImpl extends ReflectBase {
public String addr;
public String birthday;
}
Field[] declaredFields = reflect.getClass().getDeclaredFields();
# 输出在子类中定义的属性:2
System.out.println(declaredFields.length);
解决办法
使用反射方法getFields()就可以获取到从父类继承的所有public属性(注意:只能获取到从父类继承的所有public属性,其他非public属性是无法获取到的)。
// 从父类获取到所有public属性,输出:3
Field[] fields = reflect.getClass().getFields();
System.out.println(fields.length);
【参考】
https://blog.csdn.net/liujun03/article/details/81512834 Java反射获取对象成员属性,getFields()与getDeclaredFields()方法的区别
http://devgou.com/article/Java-Reflect/ Java-反射