java.lang.reflect java.lang.invoke.MethodHandle
获取 Class 对象:
Class.forName():
String className = "com.example.demo.reflect.ClaForRefTest";
Class<?> refClass = Class.forName(className);
// 首先找到调用类
// 然后使用调用类的 ClassLoader 去初始化
// forName0 是 native 方法
public static Class<?> forName(String className)
throws ClassNotFoundException {
Class<?> caller = Reflection.getCallerClass();
return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
}
ClassLoader.loadClass():
String className = "com.example.demo.reflect.ClaForRefTest";
// Launcher$AppClassLoader
Class<?> refClass = ClassLoader.getSystemClassLoader().loadClass(className);
方法调用:
String className = "com.example.demo.reflect.ClaForRefTest";
// 得到 Class 对象
Class<?> refClass = Class.forName(className);
// 获取方法:方法名和参数。(方法名和参数列表确定唯一方法,不区分静态非静态)
Method test = refClass.getMethod("test", String.class);
// 调用静态方法,不需要指定对象实例
test.invoke(null, "demojie");
// 得到对象实例
Object refObj = refClass.newInstance();
// 用对象实例和参数,调用实例方法
test.invoke(refObj, "demojie");
反射获取 Unsafe:
- Unsafe 是单例的
- 它不允许非系统类加载器(BootstrapClassLoader)加载的类去获取的
Unsafe.getUnsafe() 方法:
private static final Unsafe theUnsafe;
@CallerSensitive
public static Unsafe getUnsafe() {
Class var0 = Reflection.getCallerClass();
if (!VM.isSystemDomainLoader(var0.getClassLoader())) {
throw new SecurityException("Unsafe");
} else {
return theUnsafe;
}
}
可以使用反射直接获取里面的 theUnsafe:
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
Unsafe unsafe = (Unsafe) theUnsafe.get(null);
MethodHandle:
MethodHandles.Lookup lookup = MethodHandles.lookup();
// 方法的返回值,参数列表
MethodType methodType = MethodType.methodType(void.class, String.class);
// 找虚拟方法
MethodHandle methodHandle = lookup.findVirtual(ClaForRefTest.class, "test2", methodType);
// 使用对象调用方法
methodHandle.invokeExact(new ClaForRefTest(), "demojie");
find 的其他 API:
和反射的优缺点:
- TODO