简体   繁体   中英

How do I use reflection to access a private method?

I'm trying to access private method within reverse() in Java.

I've tried my best to make it possible, but failed at last. Can anyone help me to solve this? I just need a success run. Maybe I can change the code. Maybe I'm doing this the wrong way?

Error:

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.

My code:

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
    }
}

getDeclaredMethod needs you to pass the parameter types so that it can resolve overloaded methods.

Since your foo method has a single parameter of type String , the following should work:

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

And of course you also need to change the invoke call to pass a string.

Alternatively, you can use MethodHandles . Your Test class, rewritten to use MethodHandles . (Class Dummy is unchanged.)

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();
        }
    }
}

Note: Inspired by Method Handles in Java | Baeldung

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM