Annotations

2 respostas
Ruouri

Olá, por acaso alguem tem alguem pequeno codigo que contenha 5 annotations?
pode ser qualquer coisinha simples, meu professor pediu, mas não explicou nada, li sobre o assunto mas não entendi mtu bem ): , de como usar uma annotation

se alguem puder me enviar um codigo ficaria muito agradecido

obrigado =D

2 Respostas

B

Segue um trecho

@Validations(requiredStrings={

@RequiredStringValidator(fieldName=tarefa.descricao, message=Valor obrigatorio)

})

public class AdicionaTarefasAction extends ActionSupport {
private Tarefa tarefa;
private Calendar data;

@Action(value="adicionaTarefa", results = { 
		@Result(name="ok", location="lista-tarefas.jsp"),
		@Result(name="input", location="formulario-tarefas.jsp")
})

public String execute(){
	TarefaDAO tarefa = new TarefaDAO();
	tarefa.adiciona(this.tarefa);
	return "ok";
}

public Tarefa getTarefa() {
	return tarefa;
}

//@VisitorFieldValidator(key="tarefa")
public void setTarefa(Tarefa tarefa) {
	this.tarefa = tarefa;
}

}

ribclauport

Geralmente, nós usamos anotações, e não nos atentamos no que está acontecendo por tráz dos bastidores....

//anotação          valor de um elemento
@ClassInfo(autor="James", dataDeCriacao="30/04/2011")
public class Foo {
...
}

Para criar a anotação você criaria como abaixo, lembre-se que a palavra interface, quando se cria uma anotação se refere ao tipo anotação!

@interface ClassInfo {
String autor() default "Fulano";
String dataDeCriacao();
}

Bom vamos aos conceitos:

:idea: Anotação é um Tipo
:idea: Pode ser vista como uma espécie de interface,
declarada com auxílio do caractere @
:idea: Tipos dos elementos: primitivos, String, enum,
anotação,Class ou array de um desses tipos
:idea: Elementos podem ter valor default

Temos que considerar que se a antoação tiver apenas um elemento e ele for denominado value podemos omitir:
@interface ClassInfo { //codigo fonte da anotação
String value();
}

@ClassInfo("James")//uso da anotação em uma classe qualquer
public class Foo {

Bom antes de continuar veja que você para criar sua própria anotação, apenas salvaria o arquivo "ClassInfo.java", e sendo assim sua anotação @ClassInfo estaria
disponível para o uso como foi o exemplo acima do uso na classe Foo.

Nós temos também as restrições que dizem onde uma anotação pode ser usada sendo algumas delas:

Restrições disponíveis: [color=red] ElementType.TYPE ElementType.FIELD ElementType.METHOD ElementType.PARAMETER ... [/color]
@Target(ElementType.METHOD)
@interface MetodoTestavel {
}

@ClassInfo("James")
public class Foo {
public void m1(String arg1) {
...
}
public void m2() {
...
}
@MetodoTestavel
public void m3() {
...
}
}

Acima foi criado uma anotação chamada MetodoTestavel que está sendo aplicada no método m3(), desta forma você pode definir em quais "tipos" poderá ser usada
sua interface!

Para acabar a história nos temos a política de retenção que definem quando a anotação pode ser usada sendo elas:

[color=red]RetentionPolicy.SOURCE[/color]
? Anotações existem somente no arquivo-fonte. São
descartadas pelo compilador ao produzir uma
representação binária
[color=red]RetentionPolicy.CLASS[/color]
? Anotação são preservadas na representação binária,
mas não necessitam estar disponíveis durante a execução
[color=red]RetentionPolicy.RUNTIME[/color]
? Anotações são preservadas na representação binária da
classe e devem estar disponíveis durante a execução
através do mecanismo de reflexão.

Exemplo:
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
@interface ClassInfo {
String value();
}

Desta forma podemos facilmente tirar proveito de nossas anotações com o uso da API de refexão veja abaixo o "pedaço" de código:

Class <Foo> cls = Foo.class;
Annotation[] anots = cls.getAnnotations();
for (Annotation a: anots) {
Class ca = a.annotationType();
System.out.println( ca.getName() ); //ClassInfo
}

Veja que acima estamos "consultando" a classe e retornando as anotações que a Classe Foo possue....
Desta forma da para usar por exemplo chamada a métodos por meio de reflexion usando os proprios valores da anotação...

Para finalizar um exemplo prático, temos uma anotação chamada Teste, e uma classe Foo, vamos usar reflexion para chamar os métodos usando
os proprios valores da anotação, temos na classe Main.java três soluções possíveis para o caso. Abaixo o procedimento para você testar:

Salve anotação como Teste.java
Salve a classe Foo.java
E por fim temos uma classe de Teste que invoca os métodos passando como parâmetro os proprios valores da anotação:
Deixe a visibildade das classes transparente entre Si.

Teste.java
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Teste {
	String argumento() default "algum valor";

}
Foo.java
public class Foo {
	
    public void m1(String s) {  
    	System.out.println("m1 invocado com argumento = " + s);
    }
    
    
    @Teste(argumento="Valor para o teste 2")
    public void m2(String s) {
    	System.out.println("m2 invocado com argumento = " + s);
    }

    //@Teste(argumento="Valor para o teste 3")
    public void m3(String s) {
    	System.out.println("m3 invocado com argumento = " + s);
    }
}
Main.java
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Main {

	public static void main(String[] args) throws IllegalArgumentException,
			InstantiationException, IllegalAccessException,
			InvocationTargetException {

		solucao1();
		solucao2();
		solucao3(Teste.class, Foo.class);

	}

	private static void solucao1() throws InstantiationException,
			IllegalAccessException, IllegalArgumentException,
			InvocationTargetException {
		Class<Foo> c = Foo.class;
		Object o = c.newInstance();

		// Obtém os métodos da classe
		Method[] ms = c.getDeclaredMethods();

		for (Method m : ms) {

			Teste t = m.getAnnotation(Teste.class);
			if (t != null) {
				t.argumento();
				m.invoke(o, t.argumento());
			}
		}

	}

	private static void solucao2() throws InstantiationException,
			IllegalAccessException, IllegalArgumentException,
			InvocationTargetException {
		Class<Foo> c = Foo.class;
		Object o = c.newInstance();

		// Obtém os métodos da classe
		Method[] ms = c.getDeclaredMethods();

		for (Method m : ms) {

			Annotation[] ts = m.getAnnotations();
			for (Annotation t : ts) {
				if (t.annotationType().isAssignableFrom(Teste.class)) {
					m.invoke(o, ((Teste) t).argumento());
				}
			}

		}

	}

	private static <T extends Annotation, U> void solucao3(
			Class&lt;T&gt; tipoDaAnotacao, Class<U> c) throws InstantiationException,
			IllegalAccessException, IllegalArgumentException,
			InvocationTargetException {

		// Dos métodos declarados na anotação, verifica se existe um chamado
		// 'argumento'
		// Se não existir, retorna, pois a anotação informada como parâmetro
		// para esse método
		// não serve, pois não tem um elemento String chamado argumento.
		Method[] msa = tipoDaAnotacao.getDeclaredMethods();
		Method elemento = null;
		for (Method ma : msa) {
			if (ma.getName().equals("argumento")
					&& ma.getReturnType().equals(String.class)) {
				elemento = ma;
				break;
			}
		}
		if (elemento == null) {
			return;
		}

		U o = c.newInstance();

		// Obtém os métodos da classe
		Method[] ms = c.getDeclaredMethods();

		for (Method m : ms) {
			T t = m.getAnnotation(tipoDaAnotacao);
			if (t != null) {
				String valorArgumento = (String) elemento.invoke(t);
				m.invoke(o, valorArgumento);
			}
		}
	}

}

Espero ter ajudado!

Criado 11 de março de 2012
Ultima resposta 12 de mar. de 2012
Respostas 2
Participantes 3