Подтвердить что ты не робот

Есть ли способ передать аннотацию Java в качестве параметра?

Ребята есть способ передать Аннотацию в качестве прямого параметра (а, наоборот, делая все накладные расходы)? Например, в следующем коде у меня есть номер аннотации, который содержит значение 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);
}
4b9b3361

Ответ 1

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

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

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));
    }
}

Ответ 2

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

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 - это в основном интерфейс, вам нужно создать экземпляр анонимного класса, который реализует этот интерфейс, и передать его методу.

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

Ответ 3

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

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

Ответ 4

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

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

Ответ 5

Если вам нужно пройти аннотацию в тесте, вы можете высмеивать ее. Например, проверка проверки достоверности 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));
}