Есть ли способ передать аннотацию Java в качестве параметра? - PullRequest
26 голосов
/ 19 июля 2010

Ребята, есть ли способ передать аннотацию в качестве прямого параметра (скорее всего, выполнив все накладные расходы на отражение)?Например, в следующем коде у меня есть номер примечания, который содержит значение типа int, я хочу передать в качестве параметра методу addImpl, как я могу это сделать (кроме как путем отражения)?:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD})
public @interface Number {
    int value();
}

public void add(int x2) {
    addImpl(@Number(value = 10) lol, x2);
}

public void addImpl(Number a, int b) {
    System.out.println(a.value() + b);
}

public static void main(String[] args) {
    new TestClass().add(3);
}

Ответы [ 5 ]

21 голосов
/ 19 июля 2010

Да, вы можете передавать аннотации вот так (как если бы они были обычными интерфейсами).

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

import java.lang.annotation.*;

public class Example {

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public static @interface Number {
        int value();
    }

    @Number(value = 42)
    public int adder(final int b) throws SecurityException, NoSuchMethodException {
        Number number = getClass().getMethod("adder", int.class).getAnnotation(Number.class);
        return addImpl(number, b);
    }

    public int addImpl(final Number a, final int b) {
        return a.value() + b;
    }

    public static void main(final String[] args) throws SecurityException, NoSuchMethodException {
        System.out.println(new Example().adder(0));
    }
}
9 голосов
/ 19 июля 2010

Вы можете сделать это как:

public void add(int x2) {
    addImpl(new Number() {

        @Override
        public int value() {
            return 10;
        }

        @Override
        public Class<? extends Annotation> annotationType() {
            return Number.class;
        }
    }, x2);
}

Поскольку Number по сути является интерфейсом, вам необходимо создать экземпляр анонимного класса, реализующего этот интерфейс, и передать его методу.

Хотя почему ты хочешь это сделать, мне не под силу. Если вам нужно передать значение чему-либо, вы действительно должны использовать класс.

4 голосов
/ 19 июля 2010

Насколько мне известно, не существует такого понятия, как "литерал аннотации", поскольку вы хотите использовать его в своей реализации add.

Я думаю, что самым близким к этому было бы объявление метода, принимающего параметр типа java.lang.annotation.Annotation - но тогда вам все равно нужно будет получить эти экземпляры через отражение от объекты класса / метода.

2 голосов
/ 04 июня 2013

Если вам нужно пройти аннотацию в тесте, вы можете сделать это.Например, тест валидатора JSR 303 может выглядеть так:

public void test() {
    final TextLengthValidator validator = new TextLengthValidator();
    validator.initialize(mock(TextLength.class));
    final boolean valid = validator.isValid("some text", mock(ConstraintValidatorContext.class));
    assertThat(valid, is(true));
}
2 голосов
/ 19 июля 2010

Число также старый добрый интерфейс, вы можете реализовать конкретный класс.

Ребята, это полезно. В то время как модуль в основном имеет дело с аннотациями, которые исправляются во время компиляции, иногда нам нужно передать ему другую информацию, полученную во время выполнения из других источников (например, xml, gush!). Мы можем чрезмерно спроектировать объект или просто создать среду выполнения объект типа аннотации.

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