Java的反射机制支持通过类的名称获取类定义对应的字节码类(Class),通过字节码类可以获取类的构造函数、字段、方法。并且可以通过构造函数创建实例,可以操作指定类实例的字段,可以调用指定类实例的方法。反射不仅可以操作类的公有成员,也支持操作类的私有成员。总结说来,Java的反射机制有些类似C中的dlopen等操作.so的功能,支持程序运行中的动态扩展,广泛应用于框架类的开发。
例子:
反射构造方法
原类构造方法
public Teacher() {
this.name = "default name";
this.age = 18;
System.out.println("无参构造函数");
}
public Teacher(String name, int age) {
this.name = name;
this.age = age;
System.out.println("有参构造函数");
}
private Teacher(String name) {
this.name = name;
System.out.println("私有构造函数");
}
反射类方法
@Test
public void refConstructor1() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException,
IllegalArgumentException, InvocationTargetException {
// 方式一
Teacher teacher = (Teacher) Class.forName(className).newInstance();
// 方式二
Class clazz = Class.forName(className);
Constructor c = clazz.getConstructor(null);
c.newInstance(null);
}
@Test
public void refConstructor2() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Class clazz = Class.forName(className);
Constructor c = clazz.getConstructor(String.class, int.class);
c.newInstance("legend",32);
}
@Test
public void refConstructor3() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
Class clazz = Class.forName(className);
Constructor c = clazz.getDeclaredConstructor(String.class);
c.setAccessible(true);
c.newInstance("legend");
}
其中,Class.forName就是通过类的名称获取到类的字节码的方法。
反射字段
原类字段
public String name;
private int age;
反射类方法
@Test
public void refField() throws ClassNotFoundException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException{
Class clazz = Class.forName(className);
Teacher teacher = new Teacher();
Field f1 = clazz.getField("name");
System.out.println(f1.get(teacher));
Field f2 = clazz.getDeclaredField("age");
f2.setAccessible(true);
System.out.println(f2.get(teacher));
}
反射方法
原类方法
public void teach(String className) {
System.out.println("有参数方法");
}
public void teach(String[] className) {
System.out.println("有参数方法");
}
public String getName() {
System.out.println("有返回值方法");
return this.name;
}
public static void teach() {
System.out.println("静态方法");
}
private void teach(String className, int cycNum) {
System.out.println("私有有参方法");
}
反射类方法
@Test
public void refMethod() throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
Class clazz = Class.forName(className);
Teacher teacher = new Teacher();
Method m = clazz.getMethod("teach", String.class);
m.invoke(teacher, "English");
}
@Test
public void refMethod1() throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
Class clazz = Class.forName(className);
Teacher teacher = new Teacher();
Method m = clazz.getMethod("teach", String[].class);
m.invoke(teacher, new Object[]{new String[]{"123","456"}});
}
@Test
public void refMethod2() throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
Class clazz = Class.forName(className);
Teacher teacher = new Teacher();
Method m = clazz.getMethod("getName", null);
System.out.println(m.invoke(teacher, null));
}
@Test
public void refMethod3() throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
Class clazz = Class.forName(className);
Teacher teacher = new Teacher();
Method m = clazz.getMethod("teach", null);
m.invoke(null, null);
}
@Test
public void refMethod4() throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
Class clazz = Class.forName(className);
Teacher teacher = new Teacher();
Method m = clazz.getDeclaredMethod("teach", String.class,int.class);
m.setAccessible(true);
m.invoke(teacher, "Englist",20);
}
反射main方法
原类方法
public static void main(String[] args){
System.out.println("main函数");
}
反射类方法
@Test
public void refMain() throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
Class clazz = Class.forName(className);
Method m = clazz.getMethod("main", String[].class);
m.invoke(null, new Object[]{new String[]{"aa","bb","cc"}});
}