一、反射机制
在前面Java语法之注解自定义注解时我们也有提到反射,要获取类方法和字段的注解信息,必须通过Java的反射技术来获取 Annotation对象。那什么是反射呢?JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。它有点类似照妖镜的作用,不管是什么妖魔鬼怪(类或对象)都能看到它的真面目(获取类的属性方法、调用对象的属性方法)。
二、Class理解
反射机制可以动态获取类信息以及调用对象方法,那它是通过什么实现的呢?这就要介绍下Class类了。首先明确Class也是一个类,只是它是一个描述类的类,它也可以生成对象。对于每个类而言,在JRE中有且仅有一个不变的 Class 类型的对象,而这个Class 类型的对象只能由系统建立,封装了当前对象所对应的类的信息,有哪些属性,方法,构造器,实现了哪些接口等等。而且每个类的实例都会记得自己是由哪个Class实例所生成。
那要获取类信息或调用对象方法,肯定首先要获取到该类或对象对应的Class类的实例。一般获取Class对象有三种方式。
1. 通过类名获取 类名.class
2. 通过对象获取 对象.getClass()
3. 通过全类名获取 Class.forName(全类名)
这里我们可以使用用字符串来做验证。输出结果都是class java.lang.String。
package Reflection; public class ReflectionTest { public static void main(String[] args) throws ClassNotFoundException { //字符串的例子 Class clazz = null; //类名.class clazz = String.class; System.out.println(clazz); //对象.getClass() clazz = "ReflectionTest".getClass(); System.out.println(clazz); //Class.forName(全类名) clazz = Class.forName("java.lang.String"); System.out.println(clazz); } }
class java.lang.String class java.lang.String class java.lang.String
上面通过三种方式能获取到Class实例,然后再了解一下Class类常用的方法
|
方法名 |
功能说明 |
|
forName(String name) |
返回指定类名 name 的 Class 对象 |
|
newInstance() |
调用缺省构造函数,返回该Class对象的一个实例 |
|
newInstance(Object []args) |
调用当前格式构造函数,返回该Class对象的一个实例 |
|
getName() |
返回此Class对象所表示的实体(类、接口、数组类、基本类型或void)名称 |
|
getSuperClass() |
返回当前Class对象的父类的Class对象 |
|
getInterfaces() |
获取当前Class对象的接口 |
|
getClassLoader() |
返回该类的类加载器 |
|
getSuperclass() |
返回表示此Class所表示的实体的超类的Class |
|
getFields() |
获取类中public类型的属性 |
|
getField(String name) |
获取类特定的方法,name参数指定了属性的名称 |
|
getDeclaredFields() |
获取类中所有的属性(public、protected、default、private),但不包括继承的属性 |
|
getDeclaredField(String name) |
获取类特定的方法,name参数指定了属性的名称 |
|
getConstructors() |
获取类中的公共方法 |
|
getConstructor(Class[] params) |
获取类的特定构造方法,params参数指定构造方法的参数类型 |
|
getDeclaredConstructors() |
获取类中所有的构造方法(public、protected、default、private) |
|
getDeclaredConstructor(Class[] params) |
获取类的特定构造方法,params参数指定构造方法的参数类型 |
|
getMethods() |
获得类的public类型的方法 |
|
getMethod(String name, Class[] params) |
获得类的特定方法,name参数指定方法的名字,params参数指定方法的参数类型 |
|
getDeclaredMethods() |
获取类中所有的方法(public、protected、default、private) |
|
getDeclaredMethod(String name, Class[] params) |
获得类的特定方法,name参数指定方法的名字,params参数指定方法的参数类型 |
三、反射的使用
这里要着重介绍下上面API的使用,因为在后面要学习的Spring中IOC的原理就是反射加工厂模式。学好反射API有助于理解Spring框架内部实现。为了演示Class方法的使用,在注解demo的基础上对Person、Student类进行了修改。
Person类:
package Reflection; @CustomDescription(description="基类") @CustomDescription(description="人") public class Person { private String Name; public String getName() { return Name; } public void setName(String name) { Name = name; } public String PersonPublicMethod(String str) { return str; } public Person(String name) { Name = name; } public String PersonPrivateMethod(String str) { return str; } public Person() { super(); } }