Pergunta sobre java, enums, annotations – Existe uma maneira de declarar um atributo de anotação para * any * enum?

16

No momento, estou desenvolvendo uma estrutura de ligação baseada em anotação para Java Swing que usaLigação de JGoodies sob o capô. Infelizmente eu estou preso com uma anotação para uma ligação JRadioButton. O que eu quero fazer é especificar um nome de propriedade de um modelo que contém um valor especial (enum). O botão de rádio deve ser selecionado se esta propriedade tiver um valor específico. Agora eu quero especificar o valor na anotação assim:

<code>@RadioButtonBinding(property = "selectedItem", selectedValue = MyEnum.FIRST)
JRadioButton firstButton

@RadioButtonBinding(property = "selectedItem", selectedValue = MyEnum.SECOND)
JRadioButton secondButton
</code>

No entanto, eu não sei como declarar a anotação para permitir o acima equalquer outro enum também. Meu primeiro palpite foi esse, mas aprendi que os atributos de anotação não podem ser genéricos:

<code>@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface RadioButtonBinding {

    /** The model-property to which the selected value is bound */
    String property();

    // Idea 1: Specifying the enum class and the enum constant as String - works but is not typesafe

    Class<? extends Enum<?>> enumClass();

    String enumConstantName();

    // Idea 2: Directly specifying the enum constant - gives a compile-time error

    <T extends Enum<T>> T enumValue();

}
</code>

Alguma idéia de como resolver isso?

btw eu fiz muito desse tipo de coisa com JGoodies, um dos momentos mais miseráveis ​​que tive em Java. O maior problema é que ele tem uma classe "base" que a maioria de suas outras classes estendem e assim seus métodos têm a assinatura como método (base, base, base), onde a classe "base" passada deve ser uma instância específica, mas o assinatura não lhe dá nenhuma dica sobre qual classe específica deve ser uma instância de. A parte das ligações foi uma boa idéia, mas ele não suportou bem na época (anos atrás) e foi inacabado e documentado apenas em alemão. Bill K
A anotação RadioButtonBinding listada aqui inclui duas ideias: A primeira é especificar a classe Enum e a constante String para usar a partir dela. Mas isso não é claro e pode levar a RuntimeExceptions. O segundo é especificar o valor de um enum diretamente, mas isso não parece funcionar. Roland Schneider

Sua resposta

3   a resposta
3

Não vai funcionar do jeito que você quer. Como você descobriu, você só pode usar tipos de retorno simples nas anotações. Além disso, tentar contornar essas restrições fazendo coisas como abusar de String não vai funcionar porque você precisa estar usando uma expressão constante para inicializar os valores da anotação.

Eu acho que o mais próximo que você vai conseguir é inicializar com uma String e, em seguida, usar o código para comparar com o nome do enum (). Mas lá vai o seu tipo de segurança ...

1

Se suas enums podem implementar a mesma interface, você pode achar útil esta pergunta "Dica de codificação - tipos de interseção e java enums"

Como exatamente você usaria essa interface comum em um atributo de anotação?<T extends Enum<T> & MyInterface> T enumValue(); não funciona melhor do que sem a interface. Imre
Infelizmente não, mas obrigado pela dica de qualquer maneira. Roland Schneider
0

Eu estava tentando resolver exatamente este mesmo problema e, até onde eu sei, isso não pode ser feito. É uma chatice real.

No meu caso, eu queria especificar a anotação @Version, onde qualquer enumeração pode ser usada, e os valores enum podem ser comparados por ordinal (para encontrar a ordem das versões). Parece que eu preciso fazer o que alguns outros frameworks (como o Guice eu acho) fazem e usam duplas; pouco feio, mas funciona bem para verificações> = e <=.

Perguntas relacionadas