Java基础系列(二十三):反射进阶

运行时使用反射

上一节中我们已经知道了如何查看任意对象的数据域名称和类型:

  • 获得对应的Class对象
  • 通过Class对象调用getDeclaredFields()

那么我们如果想要在程序运行的时候获取数据域的具体值,应该怎么做呢?

问题的关键是使用Filed类的get()方法,但是因为数据域是私有的,直接去访问这个数据域的话会抛出一个异常,反射机制的默认行为受限于Java的访问控制,如果一个Java程序没有受到安全管理器的控制,就可以覆盖访问控制,为了达到这个目的我们可以使用setAccessible()方法来做到,具体做法如下:

User user = new User("Li Ming", 20, 1998, 7, 29);
Class userClass = user.getClass();
Filed f = userClass.getDeclaredFiled("name");
f.setAccessible(true);
Object v = f.get(user); // v = "Li Ming"

如果我们希望为这个域赋予一个新值,可以使用f.set(obj, value)方法将obj对象的f域设置为新值。

使用反射编写泛型数组

java.lang.reflect包中的Array类允许动态的创建数组。这里我们用到了Array类的静态方法newInstance,它能够构造新数组。在调用它的时候必须提供两个参数,一个是数组的元素类型,一个是数组的长度,数组的元素类型用于保证新创建的数组与原数组的类型保持一致。

具体实现如下:

public static Object copyOf(Object a, int newLength) {
    Class c1 = a.getClass();
    if(!c1.isArray()) {
        return null;
    }

    Class componentType = c1.getComponentType();
    int length = Array.getLength(a);
    Object newArray = Array.newInstance(componentType, newLength);
    System.arraycopy(a, 0, newArray, 0, Math.min(length, newLength));
    return newArray;
}

invoke方法

在Method类中有一个invoke方法,它允许调用包装在当前Method对象中的方法。invoke方法的签名是:

Object invoke(Object obj, Object... args);

第一个参数是隐式参数,其余的对象提供了显式参数,对于静态方法的话,第一个参数可以省略,设置为null。

如何得到相应的method对象呢?

这里需要用到Method类中的getMethod方法:

Method getMethod(String name, Class... parameterTypes)

第一个参数是方法的名称,第二个参数是方法的参数类型,这两个结合在一起就可以唯一确定一个方法,然后使用invoke进行调用。


公众号

扫码或微信搜索 Vi的技术博客,关注公众号,不定期送书活动各种福利~

image

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值