反射用途
主要用来创建框架或者工具,而不是Web应用程序。
java类的生命周期
java文件–>编译得到class文件–>类加载器把class文件加载到内存–>创建对象,运行时状态–>程序终止,死亡
Class类
在程序运行期间,java运行时系统始终为所有的实例对象维护一个称为运行时的类型标识,这个类型标识可以追踪每个实例对象对应的java类。java中有一个Class类,专门保存java类中的信息,比如域变量、构造器、方法。虚拟机可以利用对象运行时的类型信息,选择相应的方法执行。
获取Class的方法
1 getClass方法
Emploee e;//此处e只是一个可以指向Emploee类型实例的变量
Class c = e.getClass();
2 通过类的包名获得
String className = “java.util.Random”;
Class c = Class.forName(className);
3 通过变量名或类的class属性
Class c1 = Random.class;
Class c2 = int.class;
Class c3 = Double[].class;
动态创建实例的方法
Emploee e1 = e.getClass().newInstance();
Object o = Class.forName(“java.util.String”).newInstance();
深入分析Class类
在java.lang.reflect包中有三个类Field、Method、Constructor分别用于描述类的域、方法和构造器。事实上,在Class类中有三个数组分别用于存放类中的域Field、方法Method、构造器Constructor。Field、Method、Constructor中都有一个方法getModifiers,返回域或方法的修饰符情况。
Class中常用方法
Filed[] getFields()//返回类和超类的公有域
Filed[] getDeclaredFields()
Method[] getMethods()
Method[] getDeclaredMethods()
Construtor[] getConstructors()
Construtor[] getDeclaredConstructors()
获取域对象的值
Emploee harry = new Emploee("Harry",2000);
Class c = harry.getClass();
//获取name域对应的Field对象
Field f = c.getDelaredField("name");
//获取name域的值
Object v = f.get(harry);
如果name是私有域,上述get方法会抛异常。此时可以先调用setAccessible方法获取执行权。
当然也可通过
f.set(harry,value)
将harry中的name设置成新的值。
反射执行方法
public void testMyMethod() throws Exception{
Class clazz = Person.class;
Person p = (Person) clazz.newInstance();
Method m = clazz.getMethod("myMethod", String.class,int.class);
String returnValue = (String)m.invoke(p, "张三",23);
System.out.println(returnValue);
}
//下面是源文件中的myMehtod方法
private String myMethod(String name,int age){
return name+age;
}
参考文献
《java核心技术卷1》
Java基础之—反射(非常重要)