Есть ли способ избежать этой ошибки «Значение атрибута должно быть постоянным»? - PullRequest
0 голосов
/ 10 сентября 2018

У нас есть созданная нами аннотация, которая используется для проверки правильности ввода в метод. Примерно так:

@InputValidation(paramName = "foo", regularExpression = RegularExpressionConstants.FOO_REG_EX)

Наш класс RegularExpressionConstants загружен различными строковыми константами, каждый из которых представляет разные регулярные выражения. Этот класс начинал выглядеть очень грязно, поэтому я начал пытаться привести его в порядок с помощью методов, облегчающих его чтение и т. Д. Итак, теперь класс выглядит так:

public static final String FOO_REG_EX = alphanumericWithRange(1, 16);
public static final String BAR_REG_EX = alphanumericWithRange(2,4);

private static String alphanumericWithRange(int lowerLimit, int upperLimit) {
    "[a-zA-Z0-9]{" + lowerLimit + "," + upperLimit + "}";
}

Класс RegularExpressionConstants компилируется, но аннотации больше не компилируются. Ошибка Attribute value must be constant. Посмотрев на некоторые связанные вопросы по StackOverflow, я понимаю, почему это происходит. Мне в основном интересно, могу ли я как-нибудь добиться аккуратности в классе констант, не вызывая этой проблемы? Или мне просто придется иметь дело со множеством грязных констант?

Ответы [ 2 ]

0 голосов
/ 10 сентября 2018

Если вы не выполните предложение Эрнеста и не выполните рефакторинг кода, вы просто не сможете. Недостающая часть в вашем случае - это принудительное исполнение JSL (для чего постоянная времени компиляции)

инициализируется константным выражением

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

0 голосов
/ 10 сентября 2018

Вы можете использовать enum вместо списка строковых констант:

@interface InputValidation {
    RegularExpressionConstants regularExpression() default 
             RegularExpressionConstants.FOO_REG_EX;
}

Использование перечисления позволяет также перемещать метаданные name, где определен шаблон

enum RegularExpressionConstants {
    FOO_REG_EX("foo", alphanumericWithRange(1, 16)), 
    BAR_REG_EX("bar", alphanumericWithRange(2,4));

    private final String name;
    private final String pattern;

    private RegularExpression(String name, String pattern) {
        this.name = name;
        this.pattern = pattern;
    }

    public String getName() {
        return name;
    }

    public String getPattern() {
        return pattern;
    }

    private static String alphanumericWithRange(int lowerLimit, int upperLimit) {
        return "[a-zA-Z0-9]{" + lowerLimit + "," + upperLimit + "}";
    }
}

А аннотацию можно применить с помощью перечисления:

@InputValidation(regularExpression=RegularExpressionConstants.FOO_REG_EX)

Там, где обрабатывается аннотация, достаточно просто позвонить:

String pattern = field.getAnnotation(InputValidation.class)
    .regularExpression()
    .getPattern();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...