Não entendo por que não há herança nas anotações Java, assim como as classes Java. Eu acho que seria muito útil.
Por exemplo: quero saber se uma determinada anotação é um validador. Com a herança, eu poderia navegar reflexivamente pelas superclasses para saber se essa anotação estende a ValidatorAnnotation
. Caso contrário, como posso conseguir isso?
Então, alguém pode me dar uma razão para essa decisão de design?
java
inheritance
annotations
sinuhepop
fonte
fonte
java.lang.annotation.Annotation
, ou seja, qualquer anotaçãoinstanceof
, embora esse fato não seja explicitamente declarado.Respostas:
Sobre o motivo pelo qual não foi projetado dessa maneira, você pode encontrar a resposta nas Perguntas frequentes sobre o design do JSR 175 , onde diz:
Então, sim, eu acho, o motivo é apenas o KISS. De qualquer forma, parece que esse problema (junto com muitos outros) está sendo analisado como parte do JSR 308 , e você pode até encontrar um compilador alternativo com essa funcionalidade já desenvolvida por Mathias Ricken .
fonte
Anotações extensíveis aumentariam efetivamente o ônus de especificar e manter outro sistema de tipos. E esse seria um sistema de tipos bastante exclusivo, portanto você não poderia simplesmente aplicar um paradigma de tipo OO.
Pense em todos os problemas ao introduzir polimorfismo e herança em uma anotação (por exemplo, o que acontece quando a sub-anotação altera as especificações da meta-anotação, como retenção?)
E tudo isso adicionou complexidade para qual caso de uso?
Deseja saber se uma determinada anotação pertence a uma categoria?
Tente o seguinte:
Como você pode ver, você pode agrupar e categorizar anotações com facilidade, sem problemas desnecessários, usando os recursos fornecidos.
Portanto, o KISS é a razão para não introduzir um sistema do tipo meta-tipo na linguagem Java.
[ps editar]
Eu usei o String simplesmente para demonstração e em vista de uma meta-anotação aberta. Para o seu próprio projeto, obviamente, você pode usar uma enumeração de tipos de categoria e especificar várias categorias ("herança múltipla") para uma determinada anotação. Observe que os valores são totalmente falsos e apenas para fins de demonstração:
fonte
@Target(ElementType.ANNOTATION_TYPE) @Retention(RetentionPolicy.RUNTIME) @interface C {}; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @C public @interface F {} class a{ @F public void S() {} } @Test public void blahTest() throws NoSuchMethodException { Method m = a.class.getMethod("S"); System.out.println(m.isAnnotationPresent(C.class)); }
Em certo sentido, você já o possui com Anotações - meta Anotações. Se você anotar uma anotação com meta informações, isso é de várias maneiras equivalente à extensão de uma interface adicional. As anotações são interfaces, portanto o polimorfismo realmente não entra em jogo e, como são de natureza estática, não pode haver despacho dinâmico em tempo de execução.
No seu exemplo de validador, você pode obter apenas na anotação o tipo anotado e ver se ele possui uma meta-anotação de validador.
O único caso de uso que eu pude ver que a herança ajudaria é se você deseja obter a anotação por supertipo, mas isso adicionaria um monte de complexidade, porque um determinado método ou tipo pode ter duas anotações, significando que uma matriz teria que ser retornada em vez de apenas um único objeto.
Portanto, acho que a resposta final é que os casos de uso são esotéricos e complicam mais casos de uso padrão, não valendo a pena.
fonte
Os designers do suporte à anotação Java fizeram várias "simplificações" em detrimento da comunidade Java.
Nenhum subtipo de anotação torna muitas anotações complexas desnecessariamente feias. Não se pode simplesmente ter um atributo em uma anotação que possa conter uma das três coisas. É necessário ter três atributos separados, o que confunde os desenvolvedores e requer validação de tempo de execução para garantir que apenas um dos três seja usado.
Apenas uma anotação de um determinado tipo por site. Isso levou ao padrão de anotação de coleção completamente desnecessário. @Validation e @Validations, @Image e @Images, etc.
O segundo está sendo corrigido no Java 8, mas é tarde demais. Muitas estruturas foram escritas com base no que era possível no Java 5 e agora essas verrugas de API estão aqui para ficar por um bom tempo.
fonte
Posso demorar três anos para responder a essa pergunta, mas achei interessante porque me encontrei no mesmo lugar. Aqui está a minha opinião. Você pode visualizar anotações como Enums. Eles fornecem um tipo de informação unidirecional - use-a ou perca-a.
Eu tive uma situação em que queria simular GET, POST, PUT e DELETE em um aplicativo da web. Eu queria muito ter uma anotação "super" chamada "HTTP_METHOD". Mais tarde, percebi que isso não importava. Bem, eu tive que resolver usando um campo oculto no formulário HTML para identificar DELETE e PUT (porque POST e GET estavam disponíveis de qualquer maneira).
No lado do servidor, procurei um parâmetro de solicitação oculta com o nome "_method". Se o valor foi PUT ou DELETE, substituiu o método de solicitação HTTP associado. Dito isto, não importava se eu precisava ou não estender uma anotação para concluir o trabalho. Todas as anotações pareciam iguais, mas foram tratadas de maneira diferente no lado do servidor.
Portanto, no seu caso, solte a coceira para estender as anotações. Trate-os como 'marcadores'. Eles "representam" algumas informações e não necessariamente "manipulam" algumas informações.
fonte
Uma coisa em que pude pensar é na possibilidade de ter várias anotações. Assim, você pode adicionar validador e uma anotação mais específica no mesmo local. Mas eu poderia estar enganado :)
fonte
Nunca pensei nisso, mas ... parece que você está certo, não há nenhum problema com o recurso de herança de anotações (pelo menos não vejo o problema).
Sobre o seu exemplo com a anotação 'validator' - você pode explorar a abordagem de 'meta-anotação' . Ou seja, você aplica uma meta-anotação específica a toda a interface da anotação.
fonte
o mesmo problema que tenho. Não, você não pode. Eu me 'disciplinei' para escrever propriedades em anotações para respeitar alguns padrões; portanto, quando você recebe anotações, pode 'farejar' que tipo de anotação é pelas propriedades que possui.
fonte