Java利用MethodHandle實現反射時調用super的method
阿新 • • 發佈:2018-04-30
AS sta port 沒有 ase handle test ble pub
一:實現
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 */ } }
Java利用MethodHandle實現反射時調用super的method