1

In Java, I usually call a method by Reflection which uses an interface as argument by building my arguments using:

Method method = theClass.getMethod("methodName", new Class[]{ IAnyInterface.class });

But I don't know how to do this when the interface is nested in a private class: JSomething.INestedInterface, where JSomething is private:

private class JSomething {
   public void init(INestedInterface iSomething) {
       ...
   }

   public interface INestedInterface {
       public void notify();
   }

   ...
}

Here using this doesn't even compile as the interface is not accessible :

Method method = theClass.getMethod("init", new Class[]{JSomething.INestedInterface.class});

I've created a Proxy handler ready to be called, but I'm stuck trying to build a class argument when I can't use the nested interface name, any advice?

LppEdd
  • 20,274
  • 11
  • 84
  • 139
akirender
  • 13
  • 3
  • Is your private class a inner class ? If it is , see this https://stackoverflow.com/questions/14112166/instantiate-private-inner-class-with-java-reflection – howie Apr 03 '19 at 22:49
  • Do you need other clarifications? – LppEdd Apr 04 '19 at 13:56
  • Thanks. The `private` does not really exists, it was a figure of speach. The real `class` is in a file with a different package name, making the class private by default. It works fine now, I was not aware of the `$` operator ^^. Thanks again. – akirender Apr 05 '19 at 16:19

1 Answers1

1

Mmh, are you sure your code compiles by prefixing the class with private?
That visibility modifier isn't allowed for first-level classes. Per JLS 8.1.1

The access modifiers protected and private pertain only to member classes within a directly enclosing class declaration.


But anyway, you can extract the Class via Reflection, too ;)

final Class<?> clazz = Class.forName("your.package.JSomething$INestedInterface");
theClass.getMethod("methodName", new Class[]{ clazz });

Or if your JSomething class is an inner static class by itself

final Class<?> clazz = Class.forName("your.package.WrapperClass$JSomething$INestedInterface");
theClass.getMethod("methodName", new Class[]{ clazz });

Note that each "nesting level" is marked by a $ symbol, and the String you're passing in is called class' binary name (see JLS 13.1).

The binary name of a top level type (§7.6) is its canonical name (§6.7).

The binary name of a member type (§8.5, §9.5) consists of the binary name of its immediately enclosing type, followed by $, followed by the simple name of the member.


And by the way, getMethod accepts a var-arg parameter, so you can just submit a single value

theClass.getMethod("methodName", clazz);
LppEdd
  • 20,274
  • 11
  • 84
  • 139
  • Thanks. The `private` does not really exists, it was a figure of speach. The real `class` is in a file with a different package name, making the class private by default. It works fine now, I was not aware of the `$` operator ^^. Thanks again. – akirender Apr 05 '19 at 16:22