你一定记得我们写的第一个java程序 Helloworld.java吧,那个时候我们对java并没有太深的认知,就知道照书抄写然后 javac编译成Helloworld.class ,然后用java HelloWorld 执行,最后在黑屏上神奇的出现了一串“Hello java”,哈哈,也许你觉得Java好简单啊,so easy,但是我问你,你知道这背后发生的事情吗?JVM是怎么动态的调用类中的对象的呢?
是这样的,在程序运行期间,Java 运行时系统会为所有的对象维护一个被称为运行时的类型标识,其识包含了这个对象的所有相关信息,包括其构造函数信息(Constructor)、成员变量信息(Field)、方法信息(Method)和修饰符信息(Modifier),JVM根据这些信息就可以找到相应的方法,然后执行之。那你可能会有疑问,这是JVM干的事情,Jdk中有相关类可以实现吗?
答案是肯定的,Jdk中可以直接通过编码在运行时访问这些消息,保存这些信息的类是Class(java.lang.Class),可以通过任意对象的.getClass()获取。既然可以获取到Class,那jdk中一定有可以对其进行分析和行执行的类库,没错,他就是java.lang.reflect,也就是反射库,通过java.lang.reflect中的相关类,我们就可以动态的操作java程序了,也就是说你可以在程序运行的过程中,动态的调用相关方法了,例如伪码所示:InvokeMothod(Class.MethodName)。
java.lang.reflect中主要包含3个类:
Field:包含对象的成员变量相关信息
Method:对象的方法信息
Constructor:对象的构造函数信息
根据这些类,我们就可以在运行时候分析类的构造,示例1,分析类MyTestClass1的构造:
package com.reflect.test;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
/**
* 分析目标类,获取类的信息
* @author ldl
*
*/
public class GetObjectAttrTest {
public static void main(String[] args) {
//首先获取MyClass1的Class(即保存运行时信息的类)
Class c=MyTestClass1.class;
System.out.println("目标类的名称:"+c.getName());
//取出MyTestClass1的成员变量
Field[] f=c.getFields();
//获取MyTestClass1的方法列表
Method[] m=c.getMethods();
//现在我们已经取出了目标类的成员变量消息和方法信息了
//那Field和Method类里都有什么东西呢?下面进一步的分解
//1,分析Field[]
System.out.println("类包含的成员变量:");
for (Field fn:f) {
//修饰符
System.out.print(Modifier.toString(fn.getModifiers())+" ");
//数据类型
System.out.print(fn.getType()+" ");//class java.lang.String...
//变量名
System.out.print(fn.getName()+";");
System.out.println("");
}
//2,分析Method[]
System.out.println("类包含的方法:");
for (Method mn:m) {
//修饰符
System.out.print(Modifier.toString(mn.getModifiers())+" ");
//返回值的数据类型
System.out.print(mn.getReturnType()+" ");//class java.lang.String...
//方法名
System.out.print(mn.getName()+"(");
//分析方法入参
Class[] p=mn.getParameterTypes();
for (Class pn:p) {
//此处跟上面大同小异,再次省略
//步骤都是1,获取参数数据类型,2,获取参数名称
}
System.out.println("");
}
}
}
package com.reflect.test;
/**
* 示例类
* @author ZhangMeng
*
*/
public class MyTestClass1 {
public int age;
public String myName;
public String myJob;
public static void main(String[] args) {
System.out.println(showAge(26));
}
public static String showAge(int age){
return age+"岁";
}
public static int showCount(){
return 1;
}
}
输出结果为:
/** * 输出结果:
类的名称:com.reflect.test.MyTestClass1
类包含的成员变量:
public int age;
public int age;public class java.lang.String myName;
public class java.lang.String myJob;
类包含的方法:
public static class java.lang.String showAge;
public static int showCount;public static void main;
*/
获取到类的信息后,我们就可以在运行过程中动态的执行,构造之,具体示例待续。