1. 程式人生 > >Android中通過反射使用超類的私有屬性

Android中通過反射使用超類的私有屬性

自己定義的FocusLIstiew,初始化的時候讓他選定到某一行位置(不是預設的第一行的位置0),ListView預設是從第一行開始選中的,即其超類的超類AdapterView有一個私有屬性mFirstPosition ,預設為0。所以只能通過反射去修改該私有屬性。

程式碼如下:

public void setFirstPosition(int position) {

        Class superView = this.getClass(). getSuperclass(). getSuperclass(). getSuperclass();
        try {
                 Field field =  superView.getDeclaredField("mFirstPosition");
                 field.setAccessible(true);
                 field.set((AdapterView)FocusedListView.this,  position);
                 Log.d("ddd", ""  + field.get(this));
             } catch (SecurityException e) {
                    Log.d("ddd", "111111111111111111111");
                    e.printStackTrace();
             } catch (NoSuchFieldException e) {
                     Log.d("ddd", "2222222222222222222222");
                    e.printStackTrace();
            } catch (IllegalArgumentException e) {
                     Log.d("ddd", "3333333333333333333333333");
                     e.printStackTrace();
           } catch (IllegalAccessException e) {
                     Log.d("ddd", "444444444444444444444");
                     e.printStackTrace();
           }

}

在Class中提供了4個相關的方法獲得型別的屬性:
            getField(String name):Field
            getFields():Field[]
            getDeclaredField(String name):Field
            getDeclaredFields():Field[]
         其中getField用於返回一個指定名稱的屬性,但是這個屬性必須是公有的,這個屬性可以在父類中定義。如果是私有屬性或者是保護屬性,那麼都會丟擲異常提示找不到這個屬性。getFields則是返回型別中的所有公有屬性,所有的私有屬性和保護屬性都找不到。

           getDeclaredField獲得在這個型別的宣告中定義的指定名稱的屬性,這個屬性必須是在這個型別的宣告中定義,但可以使私有和保護的。getDeclaredFields獲得在這個型別的宣告中定義的所有屬性,包括私有和保護的屬性都會被返回,但是所有父類的屬性都不會被返回。