反射的原理
反射是为了能够动态的加载一个类,动态地调用一个方法,动态地访问一个属等动态要求而设计的。
它的出发点在于JVM会为每个类创建一个java.lang.Class类的实例,
通过该对象可以获取这个类的信息,然后通过使用java.lang.reflect包下的API以达到各种动态要求。
类在以下情况下会被加载:
需要使用该类创建对象。如Student s = new Student() Student会被加载
访问该类的静态成员。 如system.out.println(Calendar.MONDAY);
使用Class类的forName()方法:
类一旦被加载,JVM就会为其创建一个Class对象,如何得到一个类的Class对象?
Class.forName()返回就是一个Class对象
对象名.getClass()
类名.class
package com.common.suanfa;
public class ReflectPractice {
public static void main(String[] args) throws ClassNotFoundException {
Class<?> class1 = null;
Class<?> class2 = null;
Class<?> class3 = null;
class1 = Class.forName("com.common.suanfa.ReflectPractice");
class2 = new ReflectPractice().getClass();
class3 = ReflectPractice.class;
System.out.println("类名称 " + class1.getName());
System.out.println("类名称 " + class2.getName());
System.out.println("类名称 " + class3.getName());
}
}
output:
类名称 com.common.suanfa.ReflectPractice
类名称 com.common.suanfa.ReflectPractice
类名称 com.common.suanfa.ReflectPractice
package com.common.suanfa;
public class Teacher {
private int age;
private String name;
public Teacher() {
}
public Teacher(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
}
方便起见异常全部抛出了。
package com.common.suanfa;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ReflectPractice {
public static void main(String[] args) throws ClassNotFoundException,
NoSuchFieldException, SecurityException, InstantiationException,
IllegalAccessException, NoSuchMethodException,
IllegalArgumentException, InvocationTargetException {
// 获取类
Class c = Class.forName("com.common.suanfa.Teacher");
// 构造函数
Constructor con = c.getConstructor(int.class, String.class);
Object person = con.newInstance(20, "haha");
Field f2 = c.getDeclaredField("age");
f2.setAccessible(true);
int age = (Integer) f2.get(person);
System.out.println(age);
// 获取name属性
Field name = c.getDeclaredField("name");
// 实例化这个类赋给o
Object o = c.newInstance();
// 打破封装(不安全)
name.setAccessible(true);
// 给o对象的name属性赋值"Dave"
name.set(o, "Dave");
System.out.println(name.get(o));
// 获取对象所有属性值
Field[] field = c.getDeclaredFields();
for (Field f : field) {
System.out.println(f);
}
// 调用方法
Method method = c.getMethod("getName");
System.out.println(method.invoke(o));
}
}
output:
20
Dave
private int com.common.suanfa.Teacher.age
private java.lang.String com.common.suanfa.Teacher.name
Dave