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 {
@Override
public void draw() {
System.out.println("Drawing a circle");
}
}
// Rectangle 类
public class Rectangle implements Shape {
@Override
public 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虚拟机反射机制详解