Java反射:如何使用私有接口作为参数调用方法?

时间:2019-04-03 22:28:43

标签: java reflection interface

在Java中,我通常通过Reflection调用一个方法,该方法通过使用以下方法构建参数来使用interface作为参数:

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

但是当interface嵌套在私有类JSomething.INestedInterface中,其中JSomethingprivate时,我不知道该怎么做:

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

   public interface INestedInterface {
       public void notify();
   }

   ...
}

在这里使用它甚至无法编译,因为无法访问该接口:

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

我已经创建了一个随时可以调用的代理处理程序,但是当我无法使用嵌套的接口名称时,我被困在尝试构建class参数时,有什么建议吗?

1 个答案:

答案 0 :(得分:1)

嗯,您确定您的代码可以通过在类的前面加上private来进行编译吗?
不允许用于一级课程的可见性修饰符。每个JLS 8.1.1

  

访问修饰符protectedprivate仅与成员有关   直接包含在类声明中的类。


但是无论如何,您也可以通过反射提取Class;)

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

或者如果您的JSomething类本身是内部 static

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

请注意,每个“嵌套级别”都用$符号标记,而您传递的String被称为类的二进制名称(请参见{{ 3}})。

  

顶级类型的二进制名称(§7.6)是其规范名称(§6.7)。

     

成员类型的二进制名称(第8.5节,第9.5节)由二进制组成   其直接包含类型的名称,后跟$,后跟   成员的简单名称。


顺便说一句,getMethod接受var-arg参数,因此您只需提交一个值即可

theClass.getMethod("methodName", clazz);