關於MethodHandle類,這個類是在jdk1.7之後加入的,這個類的作用類似函數指針的意思
這個類中有一個方法
這裡我的jdk有一個問題,就是我在進行MethodHandle操作的時候,我們會發現我們的方法只能設定想要的返回值和參數,但是我們相應的方法裡面卻不能對這些方法進行操作,參數能操作的int類型的會報錯,char也會報錯
但是double類型不會出錯
1 package ch08.MethodHandle; 2 3 import java.lang.invoke.MethodHandle; 4 import java.lang.invoke.MethodType; 5 6 import static java.lang.invoke.MethodHandles.lookup; 7 8 /** 9 * 10 * 功能:測試使用MethodHandleTest這個類 11 * 時間:上午9:49:16 12 * 文件:MethodHandleTest.java 13 * 14 * @author Administrator 15 * 16 */ 17 public class MethodHandleTest 18 { 19 static class ClassA 20 { 21 public void println(String s) 22 { 23 System.out.println(s); 24 } 25 26 public void xixi(char g) 27 { 28 System.out.println("zheli shi gg" + g); 29 30 char a = 'a'; 31 a = g; 32 33 //以下片段加上就會報錯!!!! 34 // int a = 1; 35 // a = a + g; 36 //char s = (char) ('a' + g); 37 // return s; 38 } 39 } 40 41 public static void main(String[] args) throws Throwable 42 { 43 Object obj = System.currentTimeMillis() % 2 == 0 ? System.out : new ClassA(); 44 45 // 這個方法調用的結果是不論實際類型是那種,最終都可以實現對應的操作 46 //getPrintlnMH(obj).invokeExact("aksdjadj"); 47 48 getPrintXixi(obj).invokeExact(3.25); 49 } 50 51 private static MethodHandle getPrintXixi(Object clazz) throws NoSuchMethodException, IllegalAccessException 52 { 53 MethodType mt = MethodType.methodType(void.class, char.class); 54 55 return lookup().findVirtual(clazz.getClass(), "xixi", mt).bindTo(clazz); 56 } 57 58 private static MethodHandle getPrintlnMH(Object reveiver) throws Throwable 59 { 60 // 這個是方法類型,第一個參數是返回類型,第二個參數是我們的參數類型,後面還有可以有其他的類型 61 MethodType mt = MethodType.methodType(void.class, String.class); 62 63 // 這個lookup方法中find是用來查找我們制定的類裡面時候含有這個println這個類和相對應的方法類型,然後我們的bindto是返回這個方法的MethodHandle句柄 64 return lookup().findVirtual(reveiver.getClass(), "println", mt).bindTo(reveiver); 65 } 66 }
報錯還根據我麼執行的次數不同有差異!!!!
我們再看看這個
1 package ch08.MethodHandle; 2 3 import java.lang.invoke.MethodHandle; 4 import java.lang.invoke.MethodType; 5 6 import static java.lang.invoke.MethodHandles.lookup; 7 8 /** 9 * 10 * 功能:測試使用MethodHandleTest這個類 11 * 時間:上午9:49:16 12 * 文件:MethodHandleTest.java 13 * 14 * @author Administrator 15 * 16 */ 17 public class MethodHandleTest 18 { 19 static class ClassA 20 { 21 public void println(String s) 22 { 23 System.out.println(s); 24 } 25 26 public void xixi(char g) 27 { 28 System.out.println("zheli shi gg" + g); 29 30 char a = 'a'; 31 a = g; 32 33 //以下片段加上就會報錯!!!! 34 // int a = 1; 35 // a = a + g; 36 //char s = (char) ('a' + g); 37 // return s; 38 } 39 40 public void xixi(double g) 41 { 42 43 double a = 2.565; 44 45 a += g; 46 47 //好吧,如果上面這句沒有進程輸出的話,那麼就會在下一句爆粗,無法輸出!!!! 48 System.out.println("zheli shi gg" + g); 49 System.out.println("zheli shi gg" + a); 50 51 //以下片段加上就會報錯!!!! 52 // int a = 1; 53 // a = a + g; 54 //char s = (char) ('a' + g); 55 // return s; 56 } 57 } 58 59 public static void main(String[] args) throws Throwable 60 { 61 Object obj = System.currentTimeMillis() % 2 == 0 ? System.out : new ClassA(); 62 63 // 這個方法調用的結果是不論實際類型是那種,最終都可以實現對應的操作 64 //getPrintlnMH(obj).invokeExact("aksdjadj"); 65 66 getPrintXixi(obj).invokeExact(3.25); 67 } 68 69 private static MethodHandle getPrintXixi(Object clazz) throws NoSuchMethodException, IllegalAccessException 70 { 71 // MethodType mt = MethodType.methodType(void.class, char.class); 72 MethodType mt = MethodType.methodType(void.class, double.class); 73 74 return lookup().findVirtual(clazz.getClass(), "xixi", mt).bindTo(clazz); 75 } 76 77 private static MethodHandle getPrintlnMH(Object reveiver) throws Throwable 78 { 79 // 這個是方法類型,第一個參數是返回類型,第二個參數是我們的參數類型,後面還有可以有其他的類型 80 MethodType mt = MethodType.methodType(void.class, String.class); 81 82 // 這個lookup方法中find是用來查找我們制定的類裡面時候含有這個println這個類和相對應的方法類型,然後我們的bindto是返回這個方法的MethodHandle句柄 83 return lookup().findVirtual(reveiver.getClass(), "println", mt).bindTo(reveiver); 84 } 85 }
當我們的類型是double類型的時候
我們得到了相應的輸出,如果是int類型的話,那麼就會報錯,提示找不到相應的方法
而且我們吧兩句輸出中的上面一個去掉的話那麼也會報錯!!!!
具體原因是什麼還沒有得到確切的答案!!!!
如有知道,還望告知。