Можно ли создать экземпляр Java-аннотации с заданным классом <? расширяет аннотацию>? - PullRequest
5 голосов
/ 07 мая 2010

У меня есть Class<? extends Annotation> и я пытался позвонить newInstance(), но Java кричала на меня по очевидной причине, что я не могу создать интерфейс. Но я знаю, что фреймворки, такие как EasyMock, прекрасно способны создавать интерфейсы. Что нужно для того, чтобы вытащить из моей Class совершенно тупой Annotation экземпляр?

Ответы [ 4 ]

7 голосов
/ 07 мая 2010

Модельные фреймворки не создают экземпляры интерфейсов, они создают классы, которые реализуют их на лету во время выполнения. Вы можете найти этот javadoc просветительский за то, что вы хотите сделать!

7 голосов
/ 07 мая 2010

Спасибо Аффе за то, что он указал мне правильное направление - я прокомментирую его ответ, но тогда я не смогу отформатировать решение:

Annotation annotation = (Annotation) Proxy.newProxyInstance(
  clazz.getClassLoader(),
  new Class[] { Annotation.class },
  new InvocationHandler() {
    @Override public Object invoke(Object proxy, Method method, Object[] args) {
      return clazz; // only getClass() or annotationType() should be called.
    }
  });
работает как шарм.
2 голосов
/ 07 мая 2010

Вы не можете создать экземпляр класса, который не указан полностью.

Чтобы проиллюстрировать, вызов newInstance() для класса типа Class<Object> определенно создаст объект, но вызов newInstance() для класса типа Class<?> заставит компилятор задуматься, какой класс из всей вселенной возможности, которые он должен построить.

То, что вы немного сузили поле, указав, что вместо ? вам нужен ?, расширяющий Annotation, не означает, что вы на самом деле назвали определенный класс для создания. ? extends Annotation просто означает «некоторый класс, который расширяет Annotation». Без указания точного класса ClassLoader не может определить, какой конструктор вызывать, поскольку нет ограничения на количество классов, которые могут расширяться Annotation.

EasyMock не создает экземпляры интерфейсов. Я не знаком с фреймворком, но он, вероятно, создает экземпляры java.lang.Object (s), которые расширяют желаемый интерфейс, или он создает какой-то класс "закулисного" фреймворка, который был сгенерирован с помощью предложения "Implements interface" в определении класса. Интерфейсы не имеют конструктора по умолчанию.

0 голосов
/ 18 сентября 2017

Если вы знаете тип аннотации во время компиляции, вы можете просто создать класс, который реализует аннотацию, как если бы это была обычная аннотация. Смотри также этот ответ .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...