Перечисления и аннотации - PullRequest
7 голосов
/ 27 марта 2010

Я хочу использовать аннотацию в безопасном для компиляции виде.

Чтобы передать значение () в аннотацию, я хочу использовать строковое представление перечисления.

Есть ли способ использовать @A со значением из enum E?

public class T {

    public enum E {
        a,b;
    }

    // C1: i want this, but it won't compile
    @A(E.a)
    void bar() {

    // C2: no chance, it won't compile
    @A(E.a.toString())
    void bar2() {

    }
    // C3: this is ok
    @A("a"+"b")
    void bar3() {

    }

    // C4: is constant like C3, is'nt it ?
    @A(""+E.a)
    void bar4() {

    }
}

@interface A {
    String value();
}

Обновление

Мне нужен тип String в @A.

Дело в том, что я могу сделать это

@A("" + 1)
    void foo() {
}

Но здесь компилятор утверждает, что «значение атрибута должно быть постоянным». Не является ли E.a постоянной?

@A("" + E.a)
    void foo() {
}

Ответы [ 2 ]

10 голосов
/ 28 марта 2010

Проблема в том, что вы умнее компилятора :-)

E.a - это константа, а E.a.toString() - нет.Похоже, так и должно быть, но компилятор не может этого понять.

Причина, по которой работают "a"+"b" и "" + 1, заключается в том, что компилятор достаточно умен, чтобы генерировать константы во время компиляции.

Когда он видит "" + E.a, он использует E.a.toString().Вызова toString() достаточно, чтобы скинуть его.

Должен ли E быть перечислением?Вы можете попробовать:

public final class E {
  public static final String a = "a";
  public static final String b = "b";
};
7 голосов
/ 27 марта 2010

Сделать значение в аннотации типа E:

@interface A {
   E value();
}

Тогда вы можете использовать

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