Java反射机制

88 阅读3分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

什么是反射?

在程序运行时,对于任意一个类都能获取其所有属性和方法,对于任意一个对象都能够调用其所有方法,这种动态获取类和对象的信息、动态调用对象的方法的功能称为java语言的反射机制。

 

获取类的所有属性和方法

分为两步:

 

1. 获得class对象。每个类被加载后,jvm会为该类生成一个对应的Class对象。获取某个类的Class对象的方法有三种:

① 使用Class类的静态方法forName(String clazzName)。该方法需要传入某个类的全限定类名。

② 访问某个类的class属性来获取。例如,Person.class将返回Person类对应的Class对象。

③ 调用某个对象的getClass()方法。

 

2. 通过获得的class对象获取信息:

       ① 获取构造器:

方法说明
ConstructorgetConstructor(Class…parameterTypes)返回指定形参列表的public构造器
Constructor[]getConstructors()返回所有public构造器
ConstructorgetDeclaredConstructor(Class…parameterTypes)返回指定形参列表的构造器,与构造器的访问权限无关
Constructor[]getDeclaredConstructors()返回所有构造器,与构造器的访问权限无关

       ② 获取方法

方法说明
Method getMethod (String name, Class…parameterTypes)返回方法名为name, 带指定形参列表的public方法
Method[] getMethods()返回所有public方法
Method getDeclaredMethod(String name, Class…parameterTypes)返回方法名为name, 指定形参列表的方法,与方法的访问权限无关
Method[] getDeclaredMethods()返回所有方法,与方法的访问权限无关

       ③ 获取成员变量

方法说明
Field getField (String name)返回指定名称的public成员变量
Field[] getFields ()返回所有public成员变量
Field getDeclaredField(String name)返回指定名称的成员变量,与成员变量的访问权限无关
Field[] getDeclaredFields()返回所有成员变量,与成员变量的访问权限无关

       除了上述信息外,还可以获取class对象的Annotation、内部类、修饰符等,由于用的不多就不一一列举了,想了解的同学请查阅官方文档。

使用反射生成并操作对象

1. 生成对象

有两种方式:

       ① 使用class对象的newInstance()方法创建class对象对应类的实例,这种方法要求class对象对应类有默认构造器。执行newInstance()方法时实际上就是利用默认构造起来创建该类的实例

       ② 先使用class对象获取指定的Constructor对象,再调用Constructor对象的newInstance()方法创建实例。

2. 调用方法

       通过class对象获取Method对象后,调用Method对象的invoke()方法来调用。若Method对象对应的方法是private的,可以先通过Method对象.setAccessible(true)来取消java语言的访问权限检查。

3. 访问、修改成员变量的值

       通过class对象获取Field对象后,通过如下两组方法读取或设置成员变量值

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

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