Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用findVirtual调用的Methodhandle私有方法_Java_Private Methods_Methodhandle - Fatal编程技术网

Java 使用findVirtual调用的Methodhandle私有方法

Java 使用findVirtual调用的Methodhandle私有方法,java,private-methods,methodhandle,Java,Private Methods,Methodhandle,MethodHandle的Java文档说私有方法应该通过findSpecial调用 有人能解释一下我遗漏了什么吗 import java.lang.invoke.MethodHandles; import java.lang.invoke.*; import java.lang.invoke.MethodType; public class PrivateClassMethodLookupTest{ public static void main(String[] args) th

MethodHandle的Java文档说私有方法应该通过findSpecial调用

有人能解释一下我遗漏了什么吗

 import java.lang.invoke.MethodHandles;
import java.lang.invoke.*;

import java.lang.invoke.MethodType;

public class PrivateClassMethodLookupTest{
    public static void main(String[] args) throws Throwable{
     new PrivateClassMethodLookupTest().m();
     MethodHandle mh =   MethodHandles.lookup()
                .findVirtual(PrivateClassMethodLookupTest.class, "m", MethodType.methodType(void.class));
      mh.invoke(new PrivateClassMethodLookupTest());
    }

    private void m() { System.out.println("in m");}
}

您之所以能够调用它,是因为您可以从运行
main
的同一类访问私有方法 请尝试运行以下代码:

package com.company;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;

public class PrivateClassMethodLookupTest {
    public static void main(String[] args) throws Throwable {
        new PrivateClassMethodLookupTest.Inner().m();
        MethodHandle mh = MethodHandles.lookup()
                .findVirtual(PrivateClassMethodLookupTest.Inner.class, "m", MethodType.methodType(void.class));
        mh.invoke(new PrivateClassMethodLookupTest.Inner());
    }

    static class Inner {
        private void m() {
            System.out.println("in m");
        }
    }
}
要调用私有方法,应使用反射API并更改方法访问类型:

package com.company;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method;

public class PrivateClassMethodLookupTest {
    public static void main(String[] args) throws Throwable {
        new PrivateClassMethodLookupTest.Inner().m();
        Method declaredMethod = PrivateClassMethodLookupTest.Inner.class.getDeclaredMethod("m");
        declaredMethod.setAccessible(true);
        MethodHandle mh = MethodHandles.lookup().unreflect(declaredMethod);
        mh.invoke(new PrivateClassMethodLookupTest.Inner());
    }

    static class Inner {
        private void m() {
            System.out.println("in m");
        }
    }
}

有没有一种方法可以从PrivateClassMethodLookupTest调用Inner.m?MethodHandles.lookup().findSpecial(..)不起作用它可以使用反射API方法declaredMethod=PrivateClassMethodLookupTest.Inner.class.getDeclaredMethod(“m”);declaredMethod.setAccessible(true);MethodHandle mh=MethodHandles.lookup().unreflect(declaredMethod);invoke(新的PrivateClassMethodLookupTest.Inner());你知道为什么findSpecial不可能吗?从
中,如果显式指定的调用方类与查找类不相同,或者如果此查找对象没有私有访问权限,则访问失败
@nantitv:如果
内部
通过
MethodHandles.lookup()创建
查找
对象,则有可能
拥有适当的访问权限并将其交给外部类。lookup对象封装了访问,任何获得它的人都可以使用它来查找(并最终调用)关联类的
private
方法。