一:实现
1.Base类的实现
package me.silentdoer.reflecsuper; /** * @author silentdoer * @version 1.0 * @description the description * @date 4/29/18 10:19 AM */ public class Base { public String show(long num){ System.out.println("Base" + num); return "BaseResult"; } }
2.Test类的实现
package me.silentdoer.reflecsuper; /** * @author silentdoer * @version 1.0 * @description the description * @date 4/29/18 10:20 AM */ public class Test extends Base { @Override public String show(long num){ System.out.println("Test" + num); return "TestResult"; } }
3.main方法所在类的实现
package me.silentdoer.reflecsuper; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; /** * @author silentdoer * @version 1.0 * @description the description * @date 4/29/18 10:18 AM */ public class Entrance { public static void main(String[] args) throws Throwable { MethodHandle h1, h2; MethodHandles.Lookup lookup = MethodHandles.lookup(); Field allowedModes = MethodHandles.Lookup.class.getDeclaredField("allowedModes"); allowedModes.setAccessible(true); allowedModes.set(lookup, -1); // 关键,没有这三步的操作findSpecial方法内部this.checkSpecialCaller(specialCaller);会抛异常 // TODO 这里第一个参数表示最终调用的是哪个层级类的某方法,第二个参数则是方法名,第三个参数是返回值类型加参数类型,第四个参数是要调用方法的对象的类型 // TODO findSpecial是准确的要求调用第一个参数类的show方法,尽管调用的对象类是Test,注意最后一个参数的类型即Test必须是extends第一个参数(也可一样) h1 = lookup.findSpecial(Base.class, "show", MethodType.methodType(String.class, long.class), Test.class); h2 = lookup.findSpecial(Test.class, "show", MethodType.methodType(String.class, long.class), Test.class); // 用的是同一个对象,但是调用的方法却是不同层级类的show方法 Test foo = new Test(); System.out.println(h1.invoke(foo, 99L)); System.out.println(h2.invoke(foo, 99L)); /* 输出 Base99 BaseResult Test99 TestResult */ } }