Атрибут Annotation должен быть литералом класса? Почему? Константы тоже должны быть в порядке
может кто-нибудь объяснить, почему параметры аннотаций строк и классов ожидаются по-разному? Почему компилятор требует литералов для классов, а также принимает константы для строк?
рабочий пример с @RequestMapping весны:
public class MyController {
public static final String REQUEST_MAPPING = "/index.html";
@RequestMapping(MyController.REQUEST_MAPPING) // ALL OK!
...
}
ВТФ пример с @тест для TestNG это:
public class MyControllerTest {
public static final Class TEST_EXCEPTION = RuntimeException.class;
@Test(expectedExceptions = MyControllerTest.TEST_EXCEPTION) // compilation error, WTF:
// The value for annotation attribute Test.expectedExceptions must be a class literal
...
}
конечно, работает @Test (expectedExceptions = RuntimeException.класс.) Но почему? Разница только в параметре аннотации я вижу его тип: String vs Class. Почему компилятор Java также принимает строковую константу, но принимает только литералы классов?
3 ответов
спецификация языка Java не позволяет использовать константы времени компиляции с параметрами типа Class
. Можно использовать только литералы классов.
на JLS имеет следующее, чтобы сказать о подходящих значениях параметров для аннотаций:
тип элемента T соответствует значению элемента V если и только если выполняется одно из следующих условий:
- T является типом массива E[] и:
- V это ElementValueArrayInitializer и друг ElementValueInitializer (аналогично инициализатору переменной в инициализаторе массива) в V соизмерима с E. Или
- V это ElementValue в соответствии с T.
- тип V совместимо ли назначение (§5.2) С T и, кроме того:
Это-ошибка времени компиляции, если тип элемента не соответствует ElementValue.
Я не могу сказать, почему это ограничение находится в JLS.
Я получил "значение аннотации должно быть литералом класса" на следующем:
@ServerEndpoint(value="/story/notifications",
encoders = (StickerEncoder.class),
decoders = (StickerDecoder.class))
это происходит, следуя одному из учебников оракулов на websockets. Оказывается, видео не является качеством 720p, и нечеткость скрывает фигурные скобки, которые выглядят как фигурные скобки. Таким образом, ошибка исчезает при изменении скобок (скобок) для фигурных скобок.
@ServerEndpoint(value="/story/notifications",
encoders = {StickerEncoder.class},
decoders = {StickerDecoder.class})
hth любой, кто может споткнуться о то же самое в будущем.
выглядеть так:
public static final Class TEST_EXCEPTION = RuntimeException.class;
класс должен быть Throwable, который компилятор может проверить. Итак, попробуйте следующее:
public static final Class<? extends Throwable> TEST_EXCEPTION = RuntimeException.class;