Estou tentando inserir duas ou mais anotações do mesmo tipo em um único elemento, neste caso, um método. Este é o código aproximado com o qual estou trabalhando:
public class Dupe {
public @interface Foo {
String bar();
}
@Foo(bar="one")
@Foo(bar="two")
public void haha() {}
}
Ao compilar o acima, javac reclama sobre uma anotação duplicada:
max @ upsight: ~ / work / daybreak $ javac Dupe.java Dupe.java:5: anotação duplicada
Simplesmente não é possível repetir anotações como esta? Pedanticamente falando, as duas instâncias de @Foo acima não são diferentes devido ao fato de seus conteúdos serem diferentes?
Se isso não for possível, quais são algumas soluções alternativas?
ATUALIZAÇÃO: fui solicitado a descrever meu caso de uso. Aqui vai.
Estou construindo um mecanismo de sintaxe açucarado para "mapear" POJOs para armazenamentos de documentos como o MongoDB. Quero permitir que os índices sejam especificados como anotações nos getters ou setters. Aqui está um exemplo inventado:
public class Employee {
private List<Project> projects;
@Index(expr = "project.client_id")
@Index(expr = "project.start_date")
public List<Project> getProjects() { return projects; }
}
Obviamente, eu quero ser capaz de encontrar rapidamente instâncias de Employee por várias propriedades de Project. Posso especificar @Index duas vezes com valores expr () diferentes ou adotar a abordagem especificada na resposta aceita. Mesmo que o Hibernate faça isso e não seja considerado um hack, eu acho que ainda faz sentido pelo menos permitir várias anotações do mesmo tipo em um único elemento.
fonte
Respostas:
Duas ou mais anotações do mesmo tipo não são permitidas. No entanto, você pode fazer algo assim:
Porém, você precisará do tratamento dedicado da anotação Foos no código.
A propósito, acabei de usar isso 2 horas atrás para solucionar o mesmo problema :)
fonte
@Foos([@Foo(bar="one"), @Foo(bar="two")])
. Veja groovy.codehaus.org/Annotations+with+GroovyNo Java 8 (lançado em março de 2014), é possível escrever anotações repetidas / duplicadas. Consulte http://docs.oracle.com/javase/tutorial/java/annotations/repeating.html .
fonte
Além das outras formas mencionadas, existe uma forma menos prolixa em Java8:
O exemplo obtém por padrão,
FooContainer
como uma anotaçãoAmbos imprimem:
fonte
http://docs.oracle.com/javase/tutorial/java/annotations/repeating.html
A partir do Java8, você pode descrever anotações repetíveis:
Nota,
value
é um campo obrigatório para a lista de valores.Agora você pode usar anotações repetindo-as em vez de preencher a matriz:
fonte
Como disse sfussenegger, isso não é possível.
A solução usual é construir uma anotação "múltipla" , que lida com um array da anotação anterior. Normalmente é denominado o mesmo, com um sufixo 's'.
Aliás, é muito utilizado em grandes projetos públicos (Hibernate por exemplo), por isso não deve ser considerado um hack, mas sim uma solução correta para esta necessidade.
Dependendo de suas necessidades, pode ser melhor permitir que suas anotações anteriores tratem de vários valores .
Exemplo:
fonte
combinando as outras respostas da forma mais simples ... uma anotação com uma lista simples de valores ...
fonte
Se você tiver apenas 1 parâmetro "bar", pode nomeá-lo como "valor". Nesse caso, você não precisará escrever o nome do parâmetro ao usá-lo desta forma:
um pouco mais curto e mais organizado, imho ..
fonte
Na versão atual do Java, consegui resolver esse problema com a seguinte anotação:
fonte