反射的概念
在Java中反射库(reflection library)提供了一个非常丰富且精心设计的工具集,以便编写能够动态操作Java代码的程序。使用反射,可以在设计或者运行中添加新类时,能够快速地应用开发工具动态的查询新添加类的能力,使程序具有分析类能力,这样的程序称为反射。
反射机制可以用来干什么
- 在运行时分析类的能力
- 在运行时查看对象,比如,编写一个toString()方法供所有的类使用
- 实现通用的数组操作代码
- 利用Method对象,这个对象很像C++中的函数指针
- 与Java中代理一起用来创建框架,如:MVC
Java中反射实现
Java运行时系统会始终为所有的对象维护一个被称为运行时的类型标识。这个信息追踪着每个对象所属的类。虚拟机利用运行时类型信息选择相应的方法执行。
我们可以通过专门的Java类访问这些信息,保存这些信息的类为Class(此处为Java中的类,与自己创建的其他类一样)。
获得类信息的三种方法
在Java反射中一共有三种获得类信息的方法,依次如下:
1、getClass()
Class cl=element.getClass();
getClass()可以返回一个Class类型的实例,即我们可以通过它拿到element对象的类。
getName()可以拿到Class实例的名称属性,如下:
System.out.println(element.getClass().getName());
输出为element的类名。
2、forName()
Class cl=Class.forName("java.util.Random");
forName()通常用来根据类的路径获取类的信息,这个方法在创建框架时经常使用。
如果forName()中的参数不是类名或者接口名的路径时,会抛出checkedexception,所以需要提供一个异常处理器。
3、T.class
Class cl=T.class;
T是任意的Java类西行(或者void关键字),T.class即代表匹配的类型,实际上T.class还能匹配到int,但是int不是一个类,int.class反而是一个Class类型的对象。
额外插一句,我们可以用 == 来对获得的类型的对象和Class对象比较,比如:
if(element.getClass()==Element.getClass());
实例化一个类
当我们获得一个Class类对象之后,可以通过newInstance()来动态的实例化这个类,newInstance()方法调用默认的构造器。
e.getClass().newInstance();
当然我们可以使用获得类信息的三种方法来实例化一个类,我们这里只举出一个例子。
利用反射分析类的能力
在java.lang.reflect包中有三个类Field、Method、Constructor,这三个分别用于描述类的域、方法、构造器。
【他们三个 】 都有一个叫 getName() 的方法,用来返回项目的名称。
也有getModifiers(); 方法返回一个整型数值,用不同的位开关描述public static 这种修饰符的使用状况,还可以用Modifier类中的isPublic()、isPrivate或者isFinal来判断方法或着构造器是否是public、private、final。
【Field类】 中有getType();方法,用来返回描述域所属类型的Class对象。
【 Method和Constructor类】有能够返回报告参数类型的方法。
【Method】还有一个可以报告返回类型的方法
我们可以通过Class类中得getFields();、getMethods();、getConstructors(); 方法获得目标类的public域、方法和构造器数组,其中包括超类的公有成员。
通过Class类中得getDeclaredFields();、getDeclaredMethods();、getDeclaredConstructors(); 可以获得类中声明的全部域、方法、构造器,其中包括私有和受保护的成员,但不包括超类的成员。