package clazz; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; /** * @author mood321 * * è¯è¨å±é¢çæ¹æ³å¨æè°ç¨ * MethodHandles.lookup ä¸ 3 ä¸ªæ¹æ³å¯¹åºçåèç æä»¤ï¼ * * findStatic()ï¼å¯¹åº invokestatic * findVirtual()ï¼å¯¹åº invokevirtual & invokeinterface * findSpecial()ï¼å¯¹åº invokespecial * * * Java èææºæä¾äº 5 个èè´£ä¸åçæ¹æ³è°ç¨åèç æä»¤ï¼ * * invokestaticï¼è°ç¨éææ¹æ³ï¼ * invokespecialï¼è°ç¨æé 卿¹æ³ãç§ææ¹æ³ãç¶ç±»æ¹æ³ï¼ * invokevirtualï¼è°ç¨ææèæ¹æ³ï¼é¤äºéææ¹æ³ãæé 卿¹æ³ãç§ææ¹æ³ãç¶ç±»æ¹æ³ãfinal æ¹æ³çå ¶ä»æ¹æ³å«èæ¹æ³ï¼ * invokeinterfaceï¼è°ç¨æ¥å£æ¹æ³ï¼ä¼å¨è¿è¡æ¶ç¡®å®ä¸ä¸ªè¯¥æ¥å£çå®ç°å¯¹è±¡ï¼ * invokedynamicï¼å¨è¿è¡æ¶å¨æè§£æåºè°ç¨ç¹éå®ç¬¦å¼ç¨çæ¹æ³ï¼åæ§è¡è¯¥æ¹æ³ã * * MethodHandle å Reflection çåºå« * æ¬è´¨åºå«ï¼ å®ä»¬é½å¨æ¨¡ææ¹æ³è°ç¨ï¼ä½æ¯ * Reflection 模æçæ¯ Java 代ç 屿¬¡çè°ç¨ï¼ * MethodHandle 模æçæ¯åèç 屿¬¡çè°ç¨ã * å å«ä¿¡æ¯çåºå«ï¼ * Reflection ç Method 对象å å«çä¿¡æ¯å¤ï¼å æ¬ï¼æ¹æ³ç¾åãæ¹æ³æè¿°ç¬¦ãæ¹æ³çåç§å±æ§çJava端表达æ¹å¼ãæ¹æ³æ§è¡æéçï¼ * MethodHandle 对象å å«çä¿¡æ¯æ¯è¾å°ï¼æ¢å å«ä¸æ§è¡è¯¥æ¹æ³ç¸å ³çä¿¡æ¯ã */ public class MethodHandleDemo { static class ClassA { public void println(String s) { System.out.println(s); } } public static void main(String[] args) throws Throwable { /* objçéæç±»åæ¯Objectï¼æ¯æ²¡æprintlnæ¹æ³çï¼æä»¥å°½ç®¡objçå®é ç±»åé½å å«printlnæ¹æ³ï¼ å®è¿æ¯ä¸è½è°ç¨printlnæ¹æ³ */ Object obj = System.currentTimeMillis() % 2 == 0 ? System.out : new ClassA(); /* invoke()åinvokeExact()çåºå«ï¼ - invokeExact()è¦æ±æ´ä¸¥æ ¼ï¼è¦æ±ä¸¥æ ¼çç±»åå¹é ï¼æ¹æ³çè¿åå¼ç±»åä¹å¨èèèå´ä¹å - invoke()å 许æ´å æ¾æ£çè°ç¨æ¹å¼ */ getPrintlnMH(obj).invoke("Hello world"); getPrintlnMH(obj).invokeExact("Hello world"); } private static MethodHandle getPrintlnMH(Object receiver) throws NoSuchMethodException, IllegalAccessException { /* MethodTypeä»£è¡¨æ¹æ³ç±»åï¼ç¬¬ä¸ä¸ªåæ°æ¯æ¹æ³è¿åå¼çç±»åï¼ä¹åçåæ°æ¯æ¹æ³çå ¥å */ MethodType mt = MethodType.methodType(void.class, String.class); /* lookup()æ¹æ³æ¥èªäºMethodHandles.lookupï¼ è¿å¥çä½ç¨æ¯å¨æå®ç±»ä¸æ¥æ¾ç¬¦åç»å®çæ¹æ³åç§°ãæ¹æ³ç±»åï¼å¹¶ä¸ç¬¦åè°ç¨æéçæ¹æ³å¥æ */ /* å 为è¿éè°ç¨çæ¯ä¸ä¸ªèæ¹æ³ï¼æç §Javaè¯è¨çè§åï¼æ¹æ³ç¬¬ä¸ä¸ªåæ°æ¯éå¼çï¼ä»£è¡¨è¯¥æ¹æ³çæ¥æ¶è ï¼ ä¹å³æ¯thisæåç对象ï¼è¿ä¸ªåæ°ä»¥åæ¯æ¾å¨åæ°å表ä¸è¿è¡ä¼ éï¼ç°å¨æä¾äºbindTo()æ¹æ³æ¥å®æè¿ä»¶äºæ */ return MethodHandles.lookup().findVirtual(receiver.getClass(), "println", mt).bindTo(receiver); } }