当前位置: 首页 > 知识库问答 >
问题:

用java调用私有方法。lang.invoke。方法手柄

艾浩穰
2023-03-14

如何使用方法句柄调用私有方法?

据我所知,只有两种可公开访问的Lookup实例:

    方法andles.lookup
  • 方法andles.publicLookup()

两者都不允许不受限制的私人访问。

还有非公开的查找。IMPL_LOOKUP这就是我想要的。是否有某种公开的方式获得它(假设SecurityManager允许)?

共有3个答案

解柏
2023-03-14

下面是一个类似的解决方案,它在一个私有函数中包含参数(我只是碰巧有上一个项目的代码):

类名:检查ree.java

函数签名:私有字符串getSamePackagePathAndName(字符串类名称,字符串类路径)

String firstName = "John";
String lastName = "Smith";

//call the class's constructor to set up the instance, before calling the private function
InspectionTree inspectionTree = new InspectionTree(firstName, lastName);

String privateMethodName ="getSamePackagePathAndName";        
Class[] privateMethodArgClasses = new Class[] { String.class, String.class };

Method method = 
         inspectionTree.getClass().getDeclaredMethod(privateMethodName, privateArgClasses);

method.setAccessible(true);

String className = "Person";
String classPath = "C:\\workspace";

Object[] params = new Object[]{className, classPath};        

//note the return type of function 'getSamePackagePathAndName' is a String, so we cast
//the return type here as a string
String answer=  (String)method.invoke(inspectionTree, params);

method.setAccessible(false);
丌官坚秉
2023-03-14

我不知道这是不是你真正想要的。也许你可以提供更多关于你想用它实现什么的信息。但是如果你想访问查找。IMPL_LOOKUP,您可以像下面的代码示例中那样执行此操作:

public class Main {

public static void main(String[] args) {

    Lookup myLookup = MethodHandles.lookup(); // the Lookup which should be trusted
    NestedTestClass ntc = new Main().new NestedTestClass(); // test class instance

    try {
        Field impl_lookup = Lookup.class.getDeclaredField("IMPL_LOOKUP"); // get the required field via reflections
        impl_lookup.setAccessible(true); // set it accessible
        Lookup lutrusted = (Lookup) impl_lookup.get(myLookup); // get the value of IMPL_LOOKUP from the Lookup instance and save it in a new Lookup object

        // test the trusted Lookup
        MethodHandle pmh = lutrusted.findVirtual(NestedTestClass.class, "gimmeTheAnswer", MethodType.methodType(int.class));
        System.out.println(pmh.invoke(ntc));

    } catch (Throwable e) {
        e.printStackTrace();
    }

}

// nested class with private method for testing
class NestedTestClass{

    @SuppressWarnings("unused")
    private int gimmeTheAnswer(){

        return 42;
    }
}

}

它适用于JDK7,但在JDK8中可能会中断。小心!当我执行它时,我的防病毒程序发出了警报。我认为没有公开或干净的方法来做到这一点。

我有一个类似的问题,最终找到了一个解决方案:从JDK访问非公共(java本机)类(7)。

童华池
2023-03-14

事实证明,通过查找#unreflect(方法)和临时访问方法(除非在程序初始化期间完成,否则可能会带来小的安全问题)是可能的。

以下是Thorben回答中修改的主要方法:

public static void main(String[] args) {

    Lookup lookup = MethodHandles.lookup();
    NestedTestClass ntc = new Program().new NestedTestClass();

    try {
        // Grab method using normal reflection and make it accessible
        Method pm = NestedTestClass.class.getDeclaredMethod("gimmeTheAnswer");
        pm.setAccessible(true);

        // Now convert reflected method into method handle
        MethodHandle pmh = lookup.unreflect(pm);
        System.out.println("reflection:" + pm.invoke(ntc));

        // We can now revoke access to original method
        pm.setAccessible(false);

        // And yet the method handle still works!
        System.out.println("handle:" + pmh.invoke(ntc));

        // While reflection is now denied again (throws exception)
        System.out.println("reflection:" + pm.invoke(ntc));

    } catch (Throwable e) {
        e.printStackTrace();
    }

}
 类似资料:
  • 我试图模拟一个私有方法(executeGetRequest),在我声明要为私有方法返回的模拟的那一行中,私有方法实际上是用null参数执行的,因此抛出了一个NullPointerException。 VlcPlayerMinimal。爪哇: VlcPlayerMinimalTest。爪哇: 堆栈跟踪: 它似乎PowerMockito实际上是调用的方法,我试图在行PowerMockito.do返回(

  • 问题内容: 我有一个使用XML和反射将 s 返回到另一个类的类。 通常,这些对象是外部对象的子字段,但有时我想即时生成它。我已经尝试过类似的方法,但无济于事。我相信这是因为Java不允许你访问进行反射的方法。 如果提供的方法失败,则失败。我可以通过制作方法来解决它,或者制作另一个类来派生它。 长话短说,我只是想知道是否存在一种通过反射访问方法的方法。 问题答案: 你可以使用反射调用私有方法。修改已

  • 问题内容: 如何使用方法句柄调用私有方法? 据我所知,只有两种可公开访问的实例: 也不允许无限制的私人访问。 有非公开组织可以满足我的需求。是否有一些公开的方式来获取它(假设SecurityManager允许它)? 问题答案: 事实证明,可以使用Lookup#unreflect(Method)并暂时使方法可访问(除非在程序初始化期间完成,否则可能会引入小的安全性问题)。 这是Thorben的答案的

  • 我试图模仿一个私有方法,如下所示。但是,在第4行,JUnit正在调用相关的validateLanguage方法,并且由于私有方法validateLanguage在调用其他方法时引发了异常,因此没有返回模拟值。我的理解是,使用PowerMock的JUnit应该跳过validateLanguage实际实现的调用。有人能澄清一下吗?

  • 我有一节课是这样的 在我使用matutor方法时,php在调用函数abc()时发现了一个致命错误。它说从上下文调用私有方法xxx。 我所知道的oop是非常新的,私有方法/属性只能在同一个类中使用。然而,我不能调用abc(),即使它在同一个类中。 怎么会?

  • 问题内容: 我有一个具有称为的私有方法的类。我想从外面打电话。我认为应该可以反思,但是我得到了。有任何想法吗??? 问题答案: 利用使用其之前的Method对象的方法。