1 什么是Java虚拟机反射机制?
- 虚拟机在运行期间,对于任何一个类,我们都能知道其内部信息,包括属性,方法,构造函数,实现接口;对于任何一个对象,我们都能获取其字段值、调用其内部方法。这就是Java虚拟机反射机制。
2 怎么知道其内部信息,包括属性,方法,构造函数?
// 获取类对象
Class<?> clazz = MyClass.class;
Class<?> clazz = MyObject.getClass();
Class<?> clazz = Class.forName(String str)
// 获取类名
String className = clazz.getName();
// 获取父类
Class<?> superClass = clazz.getSuperclass();
// 获取实现的接口
Class<?>[] interfaces = clazz.getInterfaces();
// 获取构造函数
Constructor<?>[] constructors = clazz.getConstructors();
// 获取方法
Method[] methods = clazz.getMethods();
// 获取字段
Field[] fields = clazz.getDeclaredFields();
3 对于任何一个对象,我们怎么能获取其字段值、调用其内部方法?
//获取其字段值
Class<?> clazz = MyClass.class;
Object instance = clazz.newInstance();
Field field = clazz.getDeclaredField("fieldName");
field.setAccessible(true); // 如果字段是私有的,需要设置为可访问
Object value = field.get(instance);
field.set(instance, newValue);
//调用其内部方法
Class<?> clazz = MyClass.class;
Object instance = clazz.newInstance();
Method method = clazz.getMethod("methodName", parameterType1, parameterType2);
Object result = method.invoke(instance, arg1, arg2);
4 Java虚拟机反射机制应用?
- 主要作用是为了实现解耦,让应用编程得以像积木那样搭建。
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;// Shape 接口
public interface Shape {void draw();
}// Circle 类
public class Circle implements Shape {@Overridepublic void draw() {System.out.println("Drawing a circle");}
}// Rectangle 类
public class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("Drawing a rectangle");}
}public class ShapeFactory {public static Shape createShape(String shapeType) {try {// 使用反射获取类对象Class<?> clazz = Class.forName("com.example." + shapeType); // 假设类在com.example包下// 获取类的构造函数Constructor<?> constructor = clazz.getConstructor();// 使用构造函数创建对象Object shapeObject = constructor.newInstance();// 将对象强制转换为Shape接口类型if (shapeObject instanceof Shape) {return (Shape) shapeObject;} else {throw new IllegalArgumentException("Invalid shape type");}} catch (ClassNotFoundException | NoSuchMethodException | InstantiationException |IllegalAccessException | InvocationTargetException e) {e.printStackTrace();return null;}}public static void main(String[] args) {String userInput = "Circle"; // 用户输入的形状类型Shape shape = createShape(userInput);if (shape != null) {shape.draw(); // 调用draw方法}}
}
5 动态代理中反射是怎么应用的?
- 动态代理流程:代理类会将接口对象的方法和方法参数通过反射得到,并传递给 InvocationHandler 对象,InvocationHandler 对象,InvocationHandler 对象会聚合被代理对象,并再 invoke 方法中,调用 method.invoke(target, args),实现 被代理对象 方法的调用。
参考文献:
Java虚拟机反射机制详解