日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

methodhandle_概览Java 7 MethodHandle及其用法

發布時間:2023/12/3 java 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 methodhandle_概览Java 7 MethodHandle及其用法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

methodhandle

由于Java的Reflection API,我們已經能夠在運行時檢查和更改程序執行。 特別是,我們可以在運行時觀察接口/類/方法和字段,而無需在編譯時知道它們的名稱。

JDK 7為這種動態/運行時檢查引入了一個新的參與者,即方法句柄(即抽象類java.dyn.MethodHandle的子類)。 方法句柄為我們提供了調用非公共方法的不受限制的功能,例如,可以由訪問它的類在非公共方法上形成它。 與使用Reflection API相比,訪問檢查是在創建方法句柄時執行的,而不是每次調用該方法時都執行。

假設我們有一個需要允許對其私有方法之一進行受控訪問的類。 下面的類定義了此方法并描述了兩種訪問方法(Reflection / MethodHandle)。

public class MethodAccessExampleWithArgs {private final int i;public MethodAccessExampleWithArgs(int i_) {i = i_;}private void bar(int j, String msg) {System.out.println("Private Method \'bar\' successfully accessed : "+ i + ", " + j + " : " + msg + "!");}// Using Reflectionpublic static Method makeMethod() {Method meth = null;try {Class[] argTypes = new Class[] { int.class, String.class };meth = MethodAccessExampleWithArgs.class.getDeclaredMethod("bar",argTypes);meth.setAccessible(true);} catch (IllegalArgumentException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (SecurityException e) {e.printStackTrace();}return meth;}// Using method handlespublic static MethodHandle makeMh() {MethodHandle mh;MethodType desc = MethodType.methodType(void.class, int.class,String.class);try {mh = MethodHandles.lookup().findVirtual(MethodAccessExampleWithArgs.class, "bar", desc);System.out.println("mh=" + mh);} catch (NoAccessException e) {throw (AssertionError) new AssertionError().initCause(e);}return mh;} }

以下是一個類,用于測試訪問私有方法“ bar”的兩種方法:

public class MethodAccessMain {private static void withReflectionArgs() {Method meth = MethodAccessExampleWithArgs.makeMethod();MethodAccessExampleWithArgs mh0 = new MethodAccessExampleWithArgs(0);MethodAccessExampleWithArgs mh1 = new MethodAccessExampleWithArgs(1);try {System.out.println("Invocation using Reflection");meth.invoke(mh0, 5, "Jabba the Hutt");meth.invoke(mh1, 7, "Boba Fett");} catch (IllegalAccessException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}private static void withMhArgs() {MethodHandle mh = MethodAccessExampleWithArgs.makeMh();MethodAccessExampleWithArgs mh0 = new MethodAccessExampleWithArgs(0);MethodAccessExampleWithArgs mh1 = new MethodAccessExampleWithArgs(1);try {System.out.println("Invocation using Method Handle");mh.invokeExact(mh0, 42, "R2D2");mh.invokeExact(mh1, 43, "C3PO");} catch (Throwable e) {e.printStackTrace();}}public static void main(String[] args) {withReflectionArgs();withMhArgs();} }



如何運行代碼– JDK7 b129和Netbeans 7.0 Beta 2

上面的代碼已經在Netbeans IDE 7.0 Beta 2下使用JDK 7的內部版本129進行了測試,并且要運行,它需要以下額外的VMOptions: -XX:+ UnlockExperimentalVMOptions -XX:+ EnableMethodHandles -XX:+ EnableInvokeDynamic在“運行”>下>設置項目配置>>自定義>> VMoptions ,以便在不接收運行時異常的情況下使用InvokeDynamic和MethodHandle。

JDK7 b131和Netbeans 7.0 Beta 2的問題

如果您已升級到最新版本131,則結果將取決于編譯和運行代碼的環境。 更具體地說,Netbeans IDE 7.0 Beta 2輸出以下內容:

run: Invocation using Reflection Private Method 'bar' successfully accessed : 0, 5 : Jabba the Hutt! Private Method 'bar' successfully accessed : 1, 7 : Boba Fett!java.dyn.WrongMethodTypeException: (ILjava/lang/String;)V cannot be called as ([Ljava/lang/Object;)Ljava/lang/Object; mh=bar(MethodAccessExampleWithArgs,int,String)void Invocation using Method Handle at ben.example.MethodAccessMain.withMhArgs(MethodAccessMain.java:46) at ben.example.MethodAccessMain.main(MethodAccessMain.java:55)BUILD SUCCESSFUL (total time: 0 seconds)

JDK7 b131和Eclipse 3.6.2的問題

該示例已在Eclipse 3.6.2 Helios上使用相同的參數-XX:+ UnlockExperimentalVMOptions -XX:+ EnableMethodHandles -XX:+ EnableInvokeDynamic在“運行>>運行配置>>參數>> VM參數”下進行了進一步測試,但是我們已經提供相同的輸出。

從已經提示我們的異常中,我們可以看到,我們的方法原本是用int(I),字符串(Ljava / lang / String)調用并返回void(V)來調用的,而不是使用Object的數組,并返回一個Object。 這表明在IDE中使用的編譯器存在一些問題(可能與命令行編譯器不同)。

在命令行上運行代碼JDK7 b131

如果您碰巧在計算機上構建了129后JDK7,并且希望運行上述示例而沒有任何問題,則可能應該堅持編譯(javac)并運行( java -XX:+ UnlockExperimentalVMOptions -XX:+ EnableMethodHandles -XX:+ EnableInvokeDynamic com.wgjd.MethodHandleExample.MethodAccessMain )從命令行輸入MethodHandle代碼。

修復了JDK7 b131和IDE

目前尚無確定何時可以運行方法句柄而沒有額外的VMOptions開銷的日期,但是如果您想跟上達芬奇機器項目的最新動態,請注意動態調用的實現,確保您已訂閱其郵件列表 。

還值得一提的是,從前面提到的郵件列表中,我們發現有一個復雜的更改,該更改將多包代碼合并到一個包中,并包括準備從java.dynjava.lang的干凈重命名。調用 。 修復由于多個包之間的依賴性而導致的API中的某些缺陷是必需的。

參考文獻:

  • Java 7開發人員博客上的 JCG合作伙伴介紹了MethodHandle及其用法
  • 經驗豐富的Java開發人員

編碼愉快! 不要忘記分享!

拜倫

相關文章:

  • JDK中的設計模式
  • Java內存模型-快速概述和注意事項
  • Java Fork / Join進行并行編程
  • 依賴注入–手動方式
  • 了解和擴展Java ClassLoader

翻譯自: https://www.javacodegeeks.com/2011/03/glimpse-at-java-7-methodhandle-and-its.html

methodhandle

總結

以上是生活随笔為你收集整理的methodhandle_概览Java 7 MethodHandle及其用法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。