1、获取想要操作的类的 Class 对象,该 Class 对象是反射的核心,通过它可以调用类的任意方法。
2、调用 Class 对象所对应的类中定义的方法,这是反射的使用阶段。
3、使用反射 API 来获取并调用类的属性和方法等信息。
获取Class对象的3种方式
- 调用某个对象的
getClass()
方法以获取该类对应的 Class 对象:
Person p = new Person();
Class clazz = p.getClass();
复制代码
- 调用某个类的
class 属性
以获取该类对应的 Class 对象:
Class clazz = Person.class;
复制代码
- 调用 Class 类中的
forName()
静态方法以获取该类对应的 Class 对象,这是最安全、性能也最好的方法:
Class clazz=Class.forName(“fullClassPath”);
//fullClassPath 为类的包路径及名称(最常用)
复制代码
当我们获得了想要操作的类的 Class 对象后,可以通过 Class 类中的方法获取并查看该类中的方法和属性。
//获取 Person 类的 Class 对象
Class class=Class.forName(“reflection.Person”);
//获取 Programmer 类的所有方法信息
Method[] method=class.getDeclaredMethods();
//获取 Programmer类的所有成员属性信息
Field[] field=class.getDeclaredFields();
//获取 Programmer 类的所有构造方法信息
Constructor[] constructor=class.getDeclaredConstructors();
复制代码
通过反射创建对象的两种方式
- Class 对象调用
newInstance()
方法
使用 Class 对象的 newInstance()
方法来创建该 Class 对象对应类的实例,但是这种方法要求该Class对象对应的类有默认的空构造器。
- Constructor 构造器调用
newInstance()
方法
先使用 Class 对象获取指定的 Constructor 对象,再调用 Constructor 对象的 newInstance()
方法来创建 Class 对象对应类的实例,通过这种方法可以选定构造方法创建实例。
//获取 Programmer 类的 Class 对象
Class class=Class.forName(“reflection.Person”);
//使用newInstane 方法创建对象
Programmer p=(Person) clazz.newInstance();
//获取构造方法并创建对象
Constructor c=class.getDeclaredConstructor(String.class,String.class,Integer.class);
//创建对象并设置属性
Programmer p1=(Person) c.newInstance(“Akiang”,“男”,20);
复制代码
Java反射API
=========
- Class 类:反射的核心类,由 JVM 生成的,通过它能够获悉整个类的结构,如可以获取类的属性,方法等信息。
Class类的常用方法:
| 方法名 | 说明 |
| — | — |
| forName() | (1)获取Class对象的一个引用,但引用的类还没有加载(该类的第一个对象没有生成)就加载了这个类。 |
| | (2)为了产生Class引用,forName()立即就进行了初始化。 |
| Object-getClass() | 获取Class对象的一个引用,返回表示该对象的实际类型的Class引用。 |
| getName() | 取全限定的类名(包括包名),即类的完整名字。 |
| getSimpleName() | 获取类名(不包括包名) |
| isInterface() | 判断Class对象是否是表示一个接口 |
| getInterfaces() | 返回Class对象数组,表示Class对象所引用的类所实现的所有接口。 |
| getSuperclass() | 返回Class对象,表示Class对象所引用的类所继承的直接基类。应用该方法可在运行时发现一个对象完整的继承结构。 |
| newInstance() | 返回一个Oject对象,是实现“虚拟构造器”的一种途径。使用该方法创建的类,必须带有无参的构造器。 |
| getFields() | 获得某个类的所有的公共(public)的字段,包括继承自父类的所有公共字段。 类似的还有getMethods和getConstructors。 |
| getDeclaredFields() | 获得某个类的自己声明的字段,即包括public、private和proteced,默认但是不包括父类声明的任何字段。类似的还有getDeclaredMethods和getDeclaredConstructors。 |
- Constructor类:存在于反射包(java.lang.reflect)中,反映的是
Class
对象所表示的类的构造方法。
Class类与Constructor相关的主要方法如下:
| 方法返回值 | 方法名称 | 方法说明 |
| — | — | — |
| static Class<?> | forName(String className) | 返回与带有给定字符串名的类或接口相关联的 Class 对象。 |
| Constructor | getConstructor(Class<?>… parameterTypes) | 返回指定参数类型、具有public访问权限的构造函数对象 |
| Constructor<?>[] | getConstructors() | 返回所有具有public访问权限的构造函数的Constructor对象数组 |
| Constructor | getDeclaredConstructor(Class<?>… parameterTypes) | 返回指定参数类型、所有声明的(包括private)构造函数对象 |
| Constructor<?>[] | getDeclaredConstructor() | 返回所有声明的(包括private)构造函数对象 |
| T | newInstance() | 调用无参构造器创建此 Class 对象所表示的类的一个新实例。 |
- Field 类:Java.lang.reflec 包中的类,描述一个类中属性,包含属性的名字、数据类型、访问修饰符等,可以用来获取和设置类中的属性值。
Class类与Field对象相关方法如下:
| 方法返回值 | 方法名称 | 方法说明 |
| — | — | — |
| Field | getDeclaredField(String name) | 获取指定name名称的(包含private修饰的)字段,不包括继承的字段 |
| Field[] | getDeclaredField() | 获取Class对象所表示的类或接口的所有(包含private修饰的)字段,不包括继承的字段 |
| Field | getField(String name) | 获取指定name名称、具有public修饰的字段,包含继承字段 |
| Field[] | getField() | 获取修饰符为public的字段,包含继承字段 |
| void | set(Object obj, Object value) | 将指定对象变量上此 Field 对象表示的字段设置为指定的新值。 |