Ссылающееся значение, которое находится в перечислении в аннотации?

Я написал свою пользовательскую аннотацию и отлично работает, если я использую ее, как показано ниже.

@MyAnnotation("sun")
public void getResult(String id){


}

MyAnnotation.java

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {

    String value();

}

приведенный выше код работает нормально. Теперь вместо жесткого кодирования «солнца» я хотел бы сохранить его в Enum, как показано ниже.

public enum WeekDay{

    SUNDAY("sun"), MONDAY("mon");

    private String day;

    WeekDay(String day) {
        this.day= day;
    }


    public String getDay() {
        return this.day;
    }

}

и теперь с аннотацией я делаю, как показано ниже.

@MyAnnotation(WeekDay.SUNDAY.getDay())
    public void getResult(String id){


    }

приведенный выше код дает ошибку компиляции в eclipse. В нем говорится: Значение атрибута аннотации MyAnnotation.value должно быть постоянным выражением. Я делаю что-то не так здесь?

Спасибо!


person user755806    schedule 27.01.2014    source источник
comment
Не могли бы вы показать нам код аннотации? Кроме того, вы пробовали WeekDay.SUNDAY без .getDay() ?   -  person Silviu Burcea    schedule 27.01.2014
comment
Сильвиу, я отредактировал свой вопрос. Я попробовал ваше предложение, в котором говорится, что невозможно преобразовать WeekDay в String.   -  person user755806    schedule 27.01.2014
comment
Может быть, объявить final метод getDay()?   -  person Jorge_B    schedule 27.01.2014
comment
Хорхе, я пытался. Все та же проблема..   -  person user755806    schedule 27.01.2014
comment
@Jorge_B проверьте мой ответ, чтобы понять, почему он не работает с final в getDay()   -  person Silviu Burcea    schedule 27.01.2014


Ответы (3)


Меняться от :

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {

    String value();

}

To:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {

    WeekDay value();

}

И используйте это так:

@MyAnnotation(WeekDay.SUNDAY)

Это также будет работать, если вы передадите строковый литерал в текущую аннотацию. Пометка вашего метода как final не будет работать, потому что final для методов только предотвращает его переопределение, а не возвращает постоянное значение. Пример:

public final String getString() {
  String[] strings = { "A", "B" };
  return strings[new Random().nextInt(2)]; // returned value is not the same
}
person Silviu Burcea    schedule 27.01.2014

Все свойства аннотации оцениваются и устанавливаются во время компиляции. Метод getDay(), очевидно, должен ждать, пока код действительно запустится, чтобы вернуть значение, поэтому вы не можете использовать его для установки вещей во время компиляции!

Вы можете изменить тип значения аннотации на свое перечисление, а затем просто указать перечисление, если хотите.

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
  Weekday value();
}

@MyAnnotation(WeekDay.SUNDAY)
public void getResult(String id){
}

но это может не иметь никакого смысла, если предполагается принимать более широкий диапазон значений.

person Affe    schedule 27.01.2014

Это не сработает. Вы можете увидеть объяснение в этом ответе: https://stackoverflow.com/a/3272859/1912167

Однако вы можете определить аннотацию, чтобы принимать только перечисление:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {

    WeekDay value();

}

@MyAnnotation(WeekDay.SUNDAY)
public void getResult(String id){


}
person Tom Verelst    schedule 27.01.2014