import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

@Deprecated
class ObjetoTesteReflection implements Serializable {

	private static final long serialVersionUID = 1L;

	private Long id;
	private String nome;

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}
}

class TestMainClass {

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

		ObjetoTesteReflection obj = new ObjetoTesteReflection();

		obj.setId(13L);
		obj.setNome("Objeto para testes.");

		metodoDeTeste(obj);

	}

	private static void metodoDeTeste(Object obj) throws SecurityException,
			IllegalArgumentException, IllegalAccessException,
			InvocationTargetException {

		// Pegando a classe do objeto a manipular
		Class<?> clazz = obj.getClass();

		System.out.println("Classe:");
		System.out.println("Nome: " + clazz.getName());
		System.out.println("Anotações: ");
		for (Annotation a : clazz.getAnnotations()) {
			System.out.println("\tNome: " + a.getClass().getName());
		}
		System.out.println();

		System.out.println("Atributos:");

		// Printando os atributos dos atributos da classe na tela
		for (Field field : clazz.getDeclaredFields()) {
			System.out.print(Modifier.toString(field.getModifiers()));
			System.out.print(" " + field.getType().getName());
			System.out.println(" " + field.getName());

			// Liberando acesso ao valor do atributo
//			field.setAccessible(true);
//			System.out.println(" = " + field.get(obj));
//			field.setAccessible(false);
		}

		System.out.println("Métodos:");

		for (Method m : clazz.getMethods()) {
			System.out.print(Modifier.toString(m.getModifiers()));
			System.out.print(" " + m.getName());
			System.out.print(" " + m.getName());

			// Buscando o tipo dos parâmetros
			Class<?>[] params = m.getParameterTypes();

			// Verificando se é um método get (não precisamos aumentar a
			// complexidade do exemplo)
			if (m.getName().startsWith("get")) {
				// No nosso caso sabemos que o método não recebe parâmetros
				// Também existe m.invoke(Object objeto,Object... args)
				System.out.println(" = " + m.invoke(obj));
			}else{
				System.out.println();
			}
		}
	}
}