反射专题3

通过Class对象的getField(String name)或getFields()可以获得指定的或者全部的public成员变量;而通过getDeclaredField(String name)或getDeclaredFields()可以获得指定的或者全部的成员变量,与成员变量的访问权限无关。

Field提供了如下了如下两个方法来读取或设置成员变量:

(a)getXxx(Object obj):获取obj对象的该成员变量的值,此处Xxx对应8中基本类型,如果该成员变量的类型是引用类型,则取消get后面的Xxx。

(b)setXxx(Object obj , Xxx val):将obj对象的该成员变量设置为val值,此处Xxx对应8种基本类型,如果该成员变量的类型是引用类型,则取消set后面的Xxx。

例子1(通过反射修改成员变量):

public class Person
{
    private String name;
    private int age;

    @Override
    public String toString()
    {
        return "Person [ name: " + name + " , age: " + age + "  ]";
    }
}

下面通过反射来修改Person对象的成员变量的值:

    private void showPerson()
    {
        try
        {
            Class<?> clazz = Class.forName("com.test.zhangtao.activitytest.Person");
            Object p =  clazz.newInstance();
            //修改name属性
            Field nameField = clazz.getDeclaredField("name");
            nameField.setAccessible(true);
            nameField.set(p , "Jack");
            //修改age属性
            Field ageField = clazz.getDeclaredField("age");
            ageField.setAccessible(true);
            ageField.setInt(p , 30);

            Log.d(TAG , p.toString());
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

还有下面一种方式:

    private void showPerson()
    {
        try
        {
            Person p = new Person();
            Class<Person> clazz = Person.class;
            //修改name属性
            Field nameField = clazz.getDeclaredField("name");
            nameField.setAccessible(true);
            nameField.set(p , "Jack");
            //修改age属性
            Field ageField = clazz.getDeclaredField("age");
            ageField.setAccessible(true);
            ageField.setInt(p , 30);

            Log.d(TAG , p.toString());
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

还有下面一种方式:

    private void showPerson()
    {
        try
        {
            Person p = new Person();
            Class<?> clazz = p.getClass();
            //修改name属性
            Field nameField = clazz.getDeclaredField("name");
            nameField.setAccessible(true);
            nameField.set(p , "Jack");
            //修改age属性
            Field ageField = clazz.getDeclaredField("age");
            ageField.setAccessible(true);
            ageField.setInt(p , 30);

            Log.d(TAG , p.toString());
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

例子2(通过反射获取状态栏的高度)

protected int getStatusBarHeight()
{
    try
    {
        Class<?> c = Class.forName("com.android.internal.R$dimen");
        Object obj = c.newInstance();
        Field field = c.getField("status_bar_height");
        int x = Integer.parseInt(field.get(obj).toString());
        return getResources().getDimensionPixelSize(x);
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
    return 0;
}

-2-获取某个对象的pulic修饰的实例变量的值的通用方法

public Object getProperty(Object owner, String fieldName) throws Exception
 {
     Class ownerClass = owner.getClass();
     Field field = ownerClass.getField(fieldName);
     Object property = field.get(owner);
     return property;
}

-3-获取某个类的pulic修饰的类变量的值的通用方法

public Object getStaticProperty(String className, String fieldName) throws Exception
 {
     Class ownerClass = Class.forName(className);
     Field field = ownerClass.getField(fieldName);
     Object property = field.get(ownerClass);
     return property;
}

这里和上面有些不同,因为该属性是静态的,所以直接从类的Class里取。

-4-反射在Android中的应用

在ViewConfiguration这个类中有一个叫做sHasPermanentMenuKey的静态变量,系统就是根据这个变量的值来判断手机有没有物理Menu键的。当然这是一个内部变量,我们无法直接访问它,但是可以通过反射的方式修改它的值,让它永远为false就可以了。

private void setOverflowShowingAlways()
{
try {
ViewConfiguration config = ViewConfiguration.get(this);
Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
menuKeyField.setAccessible(true);
menuKeyField.setBoolean(config, false);
}
         catch (Exception e)
         {
e.printStackTrace();
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值