速覽Java 7 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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/374915.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/374915.shtml
英文地址,請注明出處:http://en.pswp.cn/news/374915.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

習題6-4 使用函數輸出指定范圍內的Fibonacci數 (20 分)

本題要求實現一個計算Fibonacci數的簡單函數&#xff0c;并利用其實現另一個函數&#xff0c;輸出兩正整數m和n&#xff08;0<m≤n≤10000&#xff09;之間的所有Fibonacci數。所謂Fibonacci數列就是滿足任一項數字是前兩項的和&#xff08;最開始兩項均定義為1&#xff09;…

SmartGWT入門,提供出色的GWT界面

SmartGWT簡介 我最近開始使用SmartGWT &#xff0c;它是一個基于GWT的框架&#xff0c;該框架為您的應用程序UI提供了一個全面的小部件庫&#xff0c;并為服務器端的數據管理提供了幫助。 您可以在SmartGWT展示柜上查看其漂亮的功能。 我準備了一個簡短的“入門”指南&#xf…

Android OpenGL ES(四)----調整屏幕的寬高比

1.寬高比問題 我們現在相當熟悉這樣一個事實&#xff0c;在OpenGL里&#xff0c;我們要渲染的一切物體都要映射到X軸和Y軸上[-1&#xff0c;1]的范圍內&#xff0c;對于Z軸也一樣。這個范圍內的坐標被稱為歸一化設備坐標&#xff0c;其獨立于屏幕實際尺寸或形狀。 不幸的是&…

使用Spring AOP進行面向方面的編程

面向方面的編程&#xff08;AOP&#xff09;是指將輔助功能或支持功能與主程序的業務邏輯隔離開來的編程范例。 AOP是用于分離橫切關注點的有前途的技術&#xff0c;這在面向對象的編程中通常很難做到。 以此方式增加了應用程序的模塊化&#xff0c;并且維護變得非常容易。 橫切…

面試題24 二叉搜索樹的后序遍歷序列

題目描述 輸入一個整數數組&#xff0c;判斷該數組是不是某二叉搜索樹的后序遍歷的結果。如果是則輸出Yes,否則輸出No。假設輸入的數組的任意兩個數字都互不相同。1 class Solution {2 public:3 bool VerifySquenceOfBST(vector<int> sequence) {4 if (seque…

習題6-5 使用函數驗證哥德巴赫猜想 (20 分)

本題要求實現一個判斷素數的簡單函數&#xff0c;并利用該函數驗證哥德巴赫猜想&#xff1a;任何一個不小于6的偶數均可表示為兩個奇素數之和。素數就是只能被1和自身整除的正整數。注意&#xff1a;1不是素數&#xff0c;2是素數。 函數接口定義&#xff1a; int prime( int…

Linux學習筆記 (六)用戶管理命令

一、用戶帳號 1、超級用戶&#xff1a;具有操作系統中的最高權限&#xff0c;用來管理和維護操作系統。root用戶。 2、普通用戶&#xff1a;由root用戶來創建&#xff0c;在宿主目錄中具有完全權限。 3、程序用戶&#xff1a;由應用程序添加&#xff0c;維護某個應用程序運行。…

使用Spring Security保護GWT應用程序

在本教程中&#xff0c;我們將看到如何將GWT與Spring的安全模塊&#xff08;即Spring Security&#xff09;集成在一起。 我們將看到如何保護GWT入口點&#xff0c;如何檢索用戶的憑據以及如何記錄各種身份驗證事件。 此外&#xff0c;我們將實現自定義身份驗證提供程序&#x…

用Fragment制作的Tab頁面產生的UI重疊問題

本文出處&#xff1a;http://blog.csdn.net/twilight041132/article/details/43812745 在用Fragment做Tab頁面&#xff0c;發現有時候進入應用會同時顯示多個Tab內容&#xff0c;UI發生重疊。 當應用被強行關閉后&#xff08;通過手機管家軟件手動強關&#xff0c;或系統為節省…

習題6-6 使用函數輸出一個整數的逆序數 (20 分)

本題要求實現一個求整數的逆序數的簡單函數。 函數接口定義&#xff1a; int reverse( int number );其中函數reverse須返回用戶傳入的整型number的逆序數。 我的代碼&#xff1a; int reverse( int number ) {int n number,res 0,t 0;n (n>0)?n:-n;while(n ! 0){t…

Tomcat 7上具有RESTeasy JAX-RS的RESTful Web服務-Eclipse和Maven項目

開發Web服務的RESTful方法不斷受到越來越多的關注&#xff0c;并且似乎正在將SOAP淘汰。 我不會討論哪種方法更好&#xff0c;但是我相信我們都同意REST更輕量級。 在本教程中&#xff0c;我將向您展示如何使用RESTeasy開發RESTful服務以及如何將它們部署在Tomcat服務器上。 在…

appcmd命令導入導出站點與應用程序池

在IIS7上導出所有應用程序池的方法: %windir%\system32\inetsrv\appcmd list apppool /config /xml > c:\apppools.xml 這個命令會將服務器上全部的應用程序池都導出來,但有些我們是我們不需要的,要將他們刪掉.比如: DefaultAppPoolClassic .Net AppPool如果在導入時發現同名…

卸載apache

1、運行services.msc&#xff0c;在服務中停止 apache 服務。2、運行命令行程序&#xff0c;輸入 sc delete apache&#xff0c;刪除該服務3、刪除apache文件夾。轉載于:https://www.cnblogs.com/jiangjieqim/p/5357950.html

使用wowza和xuggler將RTMP轉換為RTSP

注意&#xff1a;這是我們的“ Xuggler開發教程 ”系列的一部分。 大家好&#xff01; 在過去的三個月中&#xff0c;我們一直在進行電話會議項目。 我們認為&#xff0c;使用諸如Flex之類的技術的基于Web的應用程序將是此類要求苛刻的項目的最佳方法。 隨著軟件的復雜性和電信…

如何設置網頁標題圖標

1、先制作一個名為favicon.ico的小圖標&#xff0c;并將其放到網站根目錄下 2、在html頁面<head></head>標簽內加入&#xff1a; <link rel"shortcut icon" href"favicon.ico" />OK轉載于:https://www.cnblogs.com/moshengr/p/4600281.h…

C語言pow函數的精度問題

&#xff08;1&#xff09;pow函數返回值是double類型 &#xff08;2&#xff09;pow原型 double pow(double x,double y); (3)sqrt原型 double sqrt(double x); 當輸出時函數值賦給整型就會出錯&#xff1a; int main()d {int N 1;scanf("%d",&N);for(int i …

習題2-1 求整數均值 (10 分)

吐槽一下&#xff0c;因為少打了一個空格&#xff0c;PTA上老是不給我過&#xff0c;還一直報結果錯誤&#xff0c;誤導我好久&#xff0c;即使是吹毛求疵&#xff0c;也應該提示我格式錯誤吧&#xff01;&#xff01; 原題&#xff1a; 本題要求編寫程序&#xff0c;計算4個整…

iframe高度自適應,終于解決了

一直被iframe的高度自適應的問題困擾著&#xff0c;在項目中也是多次遇到。網上也有不少相關的代碼&#xff0c;但是總不能滿足自己的要求。在頭痛了幾次之后終于下定決心解決這個問題。 本代碼主要解決的問題是&#xff1a;最外層滾動條隨著iframe高度動態變化的問題。如果ifr…

在領域驅動的設計,貧乏的領域模型,代碼生成,依賴項注入等方面……

埃里克埃文斯&#xff08;Eric Evans&#xff09;已制定了什么是域驅動設計&#xff08;DDD&#xff09;。 Martin Fowler是DDD的大力支持者和擁護者。 這些都是非凡的名字&#xff0c;幾乎可以肯定的是&#xff0c;他們正在支持一些有價值的東西。 我不是在這里對此爭論。 也許…

Javascript模塊化工具require.js教程

轉自&#xff1a;http://www.w3cschool.cc/w3cnote/requirejs-tutorial-1.html, http://www.w3cschool.cc/w3cnote/requirejs-tutorial-2.html 隨著網站功能逐漸豐富&#xff0c;網頁中的js也變得越來越復雜和臃腫&#xff0c;原有通過script標簽來導入一個個的js文件這種方式已…