谈到反射,先来说说类文件(即class文件)加载的过程中的一个阶段,这个阶段也叫加载,主要干的事是将二进制字节流所代表的静态存储结构转化为内存中的Class对象,作为访问该类信息的一个入口。
然后,在这里简单介绍下Class对象:java虚拟机自动构造的对象,基于class文件中类的的所有信息,运行时内存中存储,对象实例具体存放在方法区中(JDK1.7及1.7之前的版本,1.8及以后存放在元数据区中),在类文件常量池中有已加载的Class对象的引用,如果要查找某个类的信息,会先在池中查找,不存在才会加载,这也是类只加载一次的原因。
Java反射机制:在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
Test:
package reflecttest;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;public class Test {
public static void main(String[] args) {
Person p = new Person();
p.setName("badegg");
p.setAge(18);
p.setId(20160001);
p.setPhone("13322221111");
sayHello(p);
}
private static void sayHello(Object o) {
System.out.println(o);Class clazz = o.getClass();
System.out.println("-------------------");
System.out.println("全限定类名:"+clazz.getName());
System.out.println("简单类名:"+clazz.getSimpleName());
System.out.println("修饰:"+Modifier.toString(clazz.getModifiers()));
System.out.println("父类:"+clazz.getSuperclass());Class[] ifs = clazz.getInterfaces();
for (Class cl : ifs) {
System.out.println("实现接口:" + cl.getName());
}Annotation[] annots = clazz.getAnnotations();
System.out.println("注解数目:"+annots.length);// 获得内部的信息
Field[] fs = clazz.getDeclaredFields();
for (Field f : fs) {
System.out.printf("字段:%s, %s, %s\n", Modifier.toString(f.getModifiers()), f.getType().getName(),
f.getName());
}// 获得方法
Method[] ms = clazz.getDeclaredMethods();
for (Method m : ms) {
System.out.printf("方法:%s, %s, %s,参数列表: %s\n", Modifier.toString(m.getModifiers()), m.getReturnType().getName(),
m.getName(), Arrays.toString(m.getParameterTypes()));
}// 获得构造方法
Constructor[] cs = clazz.getConstructors();
for (Constructor c : cs) {
System.out.printf("构造方法:%s,参数列表: %s\n", c.getName(), Arrays.toString(c.getParameterTypes()));
}
}
}
result: