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$AppClassLoaderClass<?> 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;@CallerSensitivepublic 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
