首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Java基础系列(二十三):反射进阶

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

作者头像
山禾说
发布2019-01-21 10:08:54
发布2019-01-21 10:08:54
3060
举报
文章被收录于专栏:Vi的技术博客Vi的技术博客

运行时使用反射

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

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

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

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

代码语言:javascript
复制
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,它能够构造新数组。在调用它的时候必须提供两个参数,一个是数组的元素类型,一个是数组的长度,数组的元素类型用于保证新创建的数组与原数组的类型保持一致。

具体实现如下:

代码语言:javascript
复制
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方法的签名是:

代码语言:javascript
复制
Object invoke(Object obj, Object... args);

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

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

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

代码语言:javascript
复制
Method getMethod(String name, Class... parameterTypes)

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-07-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Vi的技术博客 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 运行时使用反射
  • 使用反射编写泛型数组
  • invoke方法
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档