標籤:對象 imp 異常 輸出 over rri [] port long
一:實現
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