如何使用反射来访问私有方法?

sxissh06  于 2021-07-08  发布在  Java
关注(0)|答案(2)|浏览(750)

我正在尝试访问java中reverse()中的私有方法。
我尽力使它成为可能,但最后失败了。有人能帮我解决这个问题吗?我只需要一次成功的跑步。也许我可以修改密码。也许我做错了?
错误:

Exception in thread "main" java.lang.NoSuchMethodException: Dummy.foo()
    at java.lang.Class.getDeclaredMethod(Class.java:2130)
    at Test.main(Dummy.java:22)

Process completed.

我的代码:

import java.util.*;
import java.lang.reflect.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

class Dummy{
    private void foo(String name) throws Exception{
        BufferedReader n = new BufferedReader(new InputStreamReader(System.in));
    System.out.println("Please give name: ");
    name = n.readLine();
    StringBuffer o = new StringBuffer(name);
    o.reverse();

    System.out.print("Reversed string: "+o);
    }
}

class Test{
    public static void main(String[] args) throws Exception {
        Dummy d = new Dummy();
        Method m = Dummy.class.getDeclaredMethod("foo");
        //m.invoke(d);// throws java.lang.IllegalAccessException
        m.setAccessible(true);// Abracadabra 
        m.invoke(d);// now its OK
    }
}
7ajki6be

7ajki6be1#

或者,可以使用methodhandles。你的 Test 类,重写为使用 MethodHandles . (班级 Dummy 保持不变。)

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

public class Test {

    public static void main(String[] args) {
        MethodHandles.Lookup lookup = MethodHandles.lookup();
        MethodType methodType = MethodType.methodType(void.class, String.class);
        try {
            lookup = MethodHandles.privateLookupIn(Dummy.class, lookup);
            MethodHandle handle = lookup.findVirtual(Dummy.class, "foo", methodType);
            handle.invoke(new Dummy(), "");
        }
        catch (Throwable x) {
            x.printStackTrace();
        }
    }
}

注意:灵感来自java | baeldung中的方法句柄

ttygqcqt

ttygqcqt2#

getDeclaredMethod 需要您传递参数类型,以便它可以解析重载方法。
自从你的 foo 方法只有一个类型为的参数 String ,以下应起作用:

Method m = Dummy.class.getDeclaredMethod("foo", String.class);

当然,你也需要改变 invoke 调用传递字符串。

相关问题