JavaDocの状態MethodHandles.lookup()
は、このメソッドの呼び出し元と同じメソッド/関数/コンストラクタにアクセスする機能を返します。具体的には、呼び出し側がこのMethodHandles.Lookup機能など、いくつかのプライベートデータにアクセスできるかどうか。以下のコードは、これが誤りであることを示しています。どこが間違っているの?MethodHandle Lookupファシリティ
public class MethodHandlerAccessTest {
private static class NestedClass {
private static void foo(){}
}
@Test
public void testPrivateAccess() throws Throwable {
NestedClass.foo(); //compiles and executes perfectly
MethodType type = MethodType.methodType(void.class);
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle mh = lookup.findStatic(NestedClass.class, "foo", type);
}
}
編集:
これは私が得るものです:
にjava.lang.IllegalAccessException: MethodHandlerAccessTestから、)( MethodHandlerAccessTest $ NestedClass.fooのボイド:メンバーはプライベートです にあるjava.lang.invoke.MemberName.makeAccessException(MemberName.java:507) ( )java.lang.invoke.MethodHandles $ L ookup.checkAccess(MethodHandles.java:1182) java.lang.invoke.MethodHandles $ Lookup.checkMethod(MethodHandles.java:1162) でjava.lang.invoke.MethodHandles $ Lookup.accessStatic(MethodHandles.javaで : 591) MethodHandlerAccessTest.testPrivateAccess(MethodHandlerAccessTest.java:19で java.lang.invoke.MethodHandles $ Lookup.findStatic(MethodHandles.java:587) )sun.reflect.NativeMethodAccessorImpl.invoke0(ネイティブメソッドで )での(NativeMethodAccessorImpl.java:57)at java.lang.reflect.Method.invoke(Method.java:601)at org.junit.runners.model.FrameworkMethod $ 1.runReflectiveCall(FrameworkMethod.java:47) at org.junit.internal.runners。 org.junit.internal.runners.statements.InvokeMethod.evaluateでmodel.ReflectiveCallable.run(ReflectiveCallable.java:12) でorg.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) ( InvokeMethod.java:17) org.junit.runnersでorg.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70でorg.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)) で.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner $ 3.run(ParentRunner.java:238)at org.junit.runners.ParentRunner $ 1.schedule(ParentRunner.java:63)at org.junit.runners.ParentRunner.runChildren ParentRunner.java:236)at org.junit.runners.ParentRunner.access $ 000(ParentRunner.java:53)at org.junit.runners.ParentRunner $ 2.evaluate(ParentRunner.java:229)at org.junit。 org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) org.eclipse.jdt.internal.junit.runnerで でrunners.ParentRunner.run(ParentRunner.java:309) .TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(Remo org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runで org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) でteTestRunner.java:467) ( RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner。Javaの:197)
ありがとうございます。私は* synthetic fields/methods *について他のところで聞いたことがありますが、実際にはそれに遭遇したことはありません。なぜMethodHandleはこの動作をシミュレートしませんでしたか? lookup()メソッドのJavaDocから '呼び出し元の参照ハンドルオブジェクトにアクセスできます。呼び出し元がアクセスできるメソッドハンドルにアクセスすることができます。これには、プライベートフィールドとメソッドへのダイレクトメソッドハンドルも含まれます。このルックアップオブジェクトは、信頼できるエージェントに委譲される可能性のある機能です。 ' 私はそれを行うと予想しています。 – alexsmail
@alexsmail:コンパイラは合成メソッドを実装できますが、これを選択します。私は、JREが同じことをやろうとしているとは思っていません。 *言語*があなたに許すものと、*バイトコード*があなたに許すものとを区別することは重要です。 VMに関する限り、あなたは 'foo()'を呼び出すのではなく、アクセスする権限がありません。この言語では、特別な方法を追加して呼び出すことで、特別な権利を与えることができますが、これは単なる言語の問題です。呼び出し元(外部クラス)は実際にはVMの観点から 'foo()'にアクセスできません。 –