Отражение Java: как вызвать метод с закрытым интерфейсом в качестве аргумента? - PullRequest
1 голос
/ 04 апреля 2019

В Java я обычно вызываю метод с помощью Reflection, который использует interface в качестве аргумента, создавая мои аргументы, используя:

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

Но я не знаю, как это сделать, когда interface вложено в закрытый класс: JSomething.INestedInterface, где JSomething равно private:

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

   public interface INestedInterface {
       public void notify();
   }

   ...
}

Здесь это даже не компилируется, так как интерфейс недоступен:

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

Я создал обработчик Proxy, готовый к вызову, но я застрял, пытаясь создать аргумент class, когда не могу использовать имя вложенного интерфейса, любой совет?

1 Ответ

1 голос
/ 04 апреля 2019

Мм, вы уверены, что ваш код компилируется путем добавления префикса к классу private?
Этот модификатор видимости не разрешен для классов первого уровня.По JLS 8.1.1

Модификаторы доступа protected и private относятся только к member классам в пределах непосредственно включенного объявления класса.


Но в любом случае вы также можете извлечь Class с помощью Reflection;)

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 называется классом двоичное имя (см. JLS 13.1 ).

Двоичное имя типа верхнего уровня (§7.6) является его каноническим именем (§6.7).

Двоичный файлимя типа члена (§8.5, §9.5) состоит из двоичного имени его непосредственно включающего типа, за которым следует $, за которым следует простое имя члена.


И, кстати, getMethod принимает параметр var-arg, так что вы можете просто передать одно значение

theClass.getMethod("methodName", clazz);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...