Jason S
Jason S

Reputation: 189686

Java: reflection to invoke methods in a nonpublic class that implements a public interface

I'm trying to use reflection to invoke a method whose name and arguments are known at runtime, and I'm failing with an IllegalAccessException.

This is on an object that is an instance of a nonpublic class which implements a public interface, and I've got a brain cramp trying to remember the right way to invoke such a method.

public interface Foo
{
    public int getFooValue();
}

class FooImpl implements Foo
{
    @Override public int getFooValue() { return 42; }
}

Object foo = new FooImpl();

Given the foo object, how would I call foo.getFooValue() reflectively?

If I look through the results of foo.getClass().getMethods(), this should work but I think it causes the IllegalAccessException Is this a case where I have to call getDeclaredMethods()? Or do I have to walk through the public interfaces/superclasses and call getDeclaredMethods there?

Upvotes: 6

Views: 2233

Answers (2)

blackcompe
blackcompe

Reputation: 3190

This works:

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Ex
{
    public static void main(String[] args) throws Exception
    {
        final String methodName = "getFooValue";
        Object foo = new FooImpl();
        Class<?> c = foo.getClass();
        Method m = c.getDeclaredMethod(methodName, null);
        System.out.println(m.invoke(foo));
    }
}

interface Foo
{
    public int getFooValue();
}

class FooImpl implements Foo
{
    @Override public int getFooValue() { return 49; }
}

Upvotes: 3

Aito
Aito

Reputation: 6872

I think that you should call the getDeclaredMethods().

Here's an example:

Method methods[] = secretClass.getDeclaredMethods(); 
System.out.println("Access all the methods"); 
for (int i = 0; i < methods.length; i++) { 
   System.out.println("Method Name: " + methods[i].getName());
   System.out.println("Return type: " + methods[i].getReturnType());
   methods[i].setAccessible(true);
   System.out.println(methods[i].invoke(instance, EMPTY) + "\n");
}

By the way, a post refering to 'private classes reflection':

When it comes to bytecode (i.e. runtime) there is no such thing as a private class. This is a fiction maintained by the compiler. To the reflection API, there's a package-accessible type with a public member method.

Upvotes: 0

Related Questions