問題描述
最近在一個項目上開發的接口與業務方聯調時計算參數簽名總是對不上,經過排查后定位到原因:
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-反射
