getDeclaredFields()-Reflection反射-獲取包括父類在內的所有欄位
前言
今天Android移動端要加個新功能,所以迴歸Android程式設計師的身份.開發的過程中,發現了之前的程式碼寫的有很多問題,真的應該把時間抽出來重構一下了.
其中有反射的一個坑,工具類某方法反射獲取傳入Model的屬性值.但是當我把公共屬性抽出來做基類的時候,發現獲取不到基類的屬性值了.原因是使用了getDeclaredFields();
分析
方法 | 功能 |
---|---|
getFields() | 獲取所有public欄位,包括父類欄位 |
getDeclaredFields() | 獲取所有欄位,public和protected和private,但是不包括父類欄位 |
寫個小方法驗證一下下~
寫兩個類,裡面定義三個欄位,分別用public,protected,private修飾,
一個叫ParentModel,作為父類.
一個叫model,繼承ParentModel
/**
* 用作父類
*/
public class ParentModel {
private String p_privateField;
public String p_publicField;
protected String p_protectedField;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
/**
* 子類,繼承上面定義的用作父類的ParentModel
*/
public class Model extends ParentModel{
private String privateField;
public String publicField;
protected String protectedField;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
ok,分別使用getFields()和getDeclaredFields()獲取model的欄位,迴圈打印出來.
Field[] fs = Model.class.getFields();
Field[] fs1 = Model.class.getDeclaredFields();
for (Field f:fs) {
Log.d("getFields","getFields---"+f.getName());
}
for (Field f:fs1) {
Log.d ("getDeclaredFields","getDeclaredFields---"+f.getName());
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
見證答案的時候到了~
getFields()的列印輸出:
getDeclaredFields()的列印輸出:
測試證實了我們上面的結論是對的.
我想獲取子類和父類的所有Field
如果想用反射通過Model獲取parentModel和Model的所有欄位,怎麼辦?很明顯上面的兩個方法都是滿足不了的.那怎麼辦?
不用怕,我們遞迴Model的父類去getDeclaredFields(),程式碼如下:
List<Field> fieldList = new ArrayList<>() ;
Class tempClass = Model.class;
while (tempClass != null) {//當父類為null的時候說明到達了最上層的父類(Object類).
fieldList.addAll(Arrays.asList(tempClass .getDeclaredFields()));
tempClass = tempClass.getSuperclass(); //得到父類,然後賦給自己
}
for (Field f : fieldList) {
Log.d("getAllFields","getFields---"+f.getName());
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
可以看到我們獲取了Model和ParentModel的全部欄位,不僅如此,還多出來了兩個欄位shadow$_klass_
和shadow_monitor_
,這個是Object中的欄位.
shadow$_monitor_
和shadow$_klass_
是Android sdk21之後Object增加的兩個欄位。
如果你想遮蔽Object類的影響,可以為while迴圈再新增一個條件:
while (tmpClass !=null && !tmpClass.getName().toLowerCase().equals("java.lang.object") )
{
....
}
- 1
- 2
- 3
- 4
更新說明
2017.6.27更新:
之前被網友 lucky_god88 指出部落格反射獲取的值和真實情況不符,核實之後,已經更正為正確答案,這裡謝謝可愛的lucky_god88 發現並給我指出問題,解決問題的同時自己也在成長。同時也反省自己,以後要程式碼多加驗證,謹慎細緻,認真負責。
問題:
1.getFields() 獲取到 protected 型別欄位的值
這個原因至今沒有再次重現,很奇怪,很費解
2.getFields() 和 getDeclaredFields() 方法反射獲取多了一個欄位$change
這個和開發工具的配置有關係,好像是因為開啟了Instant run 造成的,而且Android Studio 2.2.3已經修復了,連結在這裡
參考資料
相關推薦
getDeclaredFields()-Reflection反射-獲取包括父類在內的所有欄位
前言今天Android移動端要加個新功能,所以迴歸Android程式設計師的身份.開發的過程中,發現了之前的程式碼寫的有很多問題,真的應該把時間抽出來重構一下了.其中有反射的一個坑,工具類某方法反射獲取傳入Model的屬性值.但是當我把公共屬性抽出來做基類的時候,發現獲取不到
Java反射程式碼 得到某類的所有欄位 getFields()與getDeclaredFields()區別 getMethod()和getDeclaredMethod()區別
** * 得到某類的所有欄位 * */ public void reflect2(){ try { Class cls = Class.forName("entity.UserBean");//載入UserBean類到記憶體中!獲取一個Cla
java中使用反射獲取pojo(實體)類的所有欄位值
說起反射,不得不說它實在是太強大了,通過反射就可以輕輕鬆鬆拿到各種東東,如果你想在專案中解除對某個類的依賴,可以考慮用反射。 今天跟大家分享的是通過java中的反射,獲取pojo類的所有欄位值。 &nb
內部類的繼承從而實現對父類的private欄位的引用
子類 public class SubClass extends SuperClass.InnerClass { SuperClass superClass; public SubClass (SuperClass superClass){ superClass.
java反射獲取聚合<List>屬性欄位
java反射獲取聚合<List>屬性欄位 2016年09月30日 11:59:40 閱讀數:7997 標籤: javareflect 更多 個人分類: java 需要動態的傳入一個Class的型別,然後反射到啟動的List,根
子類引用父類的靜態欄位,不會導致子類初始化
先看程式碼 // 父類 public class SuperClass { static { System.out.println("SuperClass Init!"); } public static int valu
group_concat ——sql語句在group後,組內所有欄位的獲取
經常寫sql的都知道,group處理的sql,一般是為了獲取一些統計引數,或者分組的欄位等等,如果分組後,想要獲取某個組內的所有欄位,這時就需要使用 此函式返回字串結果,其中NULL包含來自組的連線非值。NULL如果沒有非NULL值,則返回 。完整語法如下: GR
Yii2獲取指定表中的所有欄位
參考地址: https://blog.csdn.net/xinren369/article/details/51865424 public function actionTableField(){ $tableName= 'member'; (表名)
反射獲取類的所有屬性包括父類
/** * 獲取所有屬性包括父類 * @param object * @return */ public static Field[] getAllFields(Object object){ Class clazz = object.getClass();
java 反射之獲取泛型對象的所有字段與對應的值(包括父類的)
date lse 代碼 out lda ble alt http info 上代碼: public static void main(String[] args) throws IntrospectionException { SysUser obj =
180530-反射獲取泛型類的實際參數
sys party params 情況下 imp upload sbo 如果 type() 文章鏈接:https://liuyueyi.github.io/hexblog/2018/05/30/180530-通過反射獲取泛型類的實際參數/ 反射獲取泛型類的實際參數 泛型用得
java反射機制——獲取位元組碼對應類中的欄位
package cn.itcast.reflect.demo; import java.lang.reflect.Field; public class ReflectDemo3 { public static void main(String[] args) throws ClassNot
【java】如何通過反射獲取泛型類
核心程式碼:(編寫在父類中) public class BaseDaoImpl<T> implements BaseDao<T> { private Class<
java反射——獲取一個Object物件內的一切!
有些時候你明明知道這個object裡面是什麼,但是因為種種原因,你不能將它轉化成一個物件,只是想單純地提取出這個object裡的一些東西,這個時候就需要用反射了。 假如你這個類是這樣的: private class User { String userName;
java反射獲取泛型類
public class Person<T> { } import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; public class Student ext
(繼承方式)反射獲取泛型類的型別和物件
1.工具類,用於獲取泛型類的型別和物件public abstract class FatherReflectUtils<T> { public T getTInstance() th
Java反射:通過父類物件呼叫子類方法
通常情況下在父類中不能直接呼叫子類中的方法(重寫的除外),但是在某些特殊的情況下,需要根據一個父類的物件來呼叫子類的方法,原理就使用java的反射原理。例如:Person類,有一個name屬性publ
Eclipse4.7使用基礎 在創建類的時候,進行設置自動實現抽象父類的所有抽象方法
sleep 所有 png 2-2 finish highlight lips ner eclipse os :windows7 x64 jdk:jdk-8u131-windows-x64 ide:Eclipse Oxygen Release (4.7.0
java利用反射獲取某個包下的所有獲取物件屬性、方法、並例項化
首先貼上用到的jar包,當然也可以通過遞迴file.list獲取類的路徑名稱。 maven匯入jar包: <dependency> <groupId>
java反射機制 以及通過反射獲得類的變數欄位,方法,建構函式
Class clz =Class.forName("day_29_ReflectAndJson.Person"); //前面獲取本類及其父類共有的方法就不再寫了 直接獲得本類中的所有方法 並傳引數後呼叫本方法 Method[] method=clz.getDec