要详细的了解Java反射,就得要了解Java的类加载以及何为运行时动态加载等等概念。本文抛开其余概念,简单介绍Java反射,详细介绍会在以后有一个系统而全面的认识过后展开。
反射是Java被视为动态语言的关键,它允许程序在运行时取得任何类的内部信息。Java的这个能力或许在Web应用中用得不是很多,但在一些Java组件开发过程中非常常见,比如Spring、Hibernate等都以此为基础。了解并熟知Java反射机制对我们了解Java框架有很大的帮助。
我们首先写好一个Test类,并将它编译为class字节码。
1 /** 2 * @author turbo 3 * 4 * 2016年9月17日 5 */ 6 public class Test { 7 public void test(){ 8 System.out.println("类加载反射测试"); 9 } 10 }
编译好过后,我们在eclipse中另外新建一个包并新建一个Main.java类,将此Test.class文件放入eclipse工作空间的.bin目录的该文件夹类。此时我们在eclipse的工程中看到的目录如下:
我们在eclipse的工作空间的.bin目录看到的文件如下:
我们通常的写法是两个Java文件互相调用,现在只有class文件,要怎么来调用Test类中的方法呢?我们来看看Main.java类是怎么做到的。
1 package day_12_class; 2 3 import java.lang.reflect.Method; 4 5 /** 6 * @author turbo 7 * 8 * 2016年9月17日 9 */ 10 public class Main { 11 12 /** 13 * @param args 14 * 15 */ 16 public static void main(String[] args) throws Exception { 17 Class<?> clazz = Class.forName("Test"); 18 Object object = clazz.newInstance(); 19 Method method = clazz.getMethod("test"); 20 method.invoke(object); 21 } 22 23 }
首先来了解Class类是什么,JVM通常使用运行时类型信息选择正确方法去执行,用来保存这些类型信息的类就是Class类。每个Java类在运行时在JVM里都表现为一个Class对象,如上表示可通过调用静态方法forName通过Test类名返回Class对象。此时还是Class对象,注意它不是Object类,通过调用Class的newInstance方法来返回一个实例。
Method类提供关于类或接口上某个方法的信息,它用来封装反射类方法的一个类。同样通过Class的getMethod方法传入方法名来返回Method类。关于getMethod方法的API描述如下:
获取Method类后我们调用invoke方法即可执行Test类中的test方法。关于invoke方法的API如下:
最后我们来看看执行结果:
成功利用Java反射机制调用Test类中的方法。
由于对Java反射、类加载等知识认识得还不够全面和深入,不敢在此乱讲,所以这里只初始Java反射是个什么,它怎么用用在什么地方,它的执行过程到底是怎么样的,它的原理是什么等等还有待去深入学习。