Just another development blog

Expandmenu Shrunk


  • Command line console em Java

    Estava entediado esses dias e acabei tendo a ideia de criar uma simulação de um console de comandos em Java… A ideia era criar uma estrutura simples que permitisse que você ao menos navegasse na estrutura de pastas do sistema. Não sei se existem ferramentas semelhantes por aí, mas achei que valeria a pena o aprendizado…

    A princípio a ideia era trabalhar apenas com os pacotes nativos do Java, porém não consegui encontrar uma forma de buscar no path da aplicação por implementações de interfaces ou por classes anotadas… Depois de pesquisar um pouco acabei achando que seria interessante usar para isto o Google Reflections (que é o mecanismo utilizado pelo VRaptor para essa mesma função)… O projeto ainda esta evoluindo, ainda não consegui finalizar, mas os já aceita os comandos cat, ls, cd (com algumas restrições, mas funciona)… Há um rascunho de um loader para acrescentar mais comandos (ainda não reescrevi após alterar a forma de buscar os comandos para usar o CommandVault (um repositório com os comandos disponíveis) ao invés de montar o nome das classes manipulando Strings

    Como este projeto está disponível acredito que não preciso postar trechos de código por aqui…

    Repositório command console.

     


  • Blog de casa nova

    E eis que a galera desistiu de Zion (nome dado ao servidor que hospedava o blog até o fim do mês passado) e eu tive que arrumar outro lugar para hospedá-lo… Depois de pesquisar alguns serviços percebi que ou os preços são altos ou o serviço tende a não ser dos melhores… Isso me deu coragem pra procurar um VPS em desses clouds da vida (principalmente depois de ter ouvido certas coisas sobre o cPanel, que é o painel utilizado em praticamente todos os serviços de hospedagem por aí)…

    Resolvi contratar um plano VPS simples pra manter o blog e talvez futuramente começar a brincar com outras coisas nele…

    E graças ao amigo Jorge Luiz do Geek War Machine, que permitiu que o explorasse, o server está funcionando redondinho… Valeu, rapaz…

    E pra inaugurar a casa nova estou preparando um texto (que eu acho) legal…


  • Retrospectiva 2011

    Depois de ver alguns posts por aí acabei resolvendo escrever algo nessa linha… Tentar recapitular o que rolou esse ano…

    É engraçado como é difícil escolher por onde começar… rsrs. Mas tentemos do início…

    Meu início de ano foi bem corrido, mas não tenho do que reclamar, aprendi muito nesse período… Comecei a mexer com portlets, comecei a utilizar na prática coisas que já vinha estudando há algum tempo e que no trabalho anterior eu não tinha autonomia suficiente pra usar esse tipo de coisa… Comecei a me policiar mais com legibilidade e organização de código (sempre dei mais importância a firulas no algoritmo que na “beleza” do conteúdo, tenho que confessar)… Com isso resolvi ao menos iniciar alguns projetos pessoais, principalmente para ter algo como foco pra estudar coisas novas…

    Outra coisa muito importante que ocorreu este ano foi ter ido a um Openspace (acho que o sexto), que rolou no CEFET… Ali vi alguns códigos que o pessoal fez pra rodar no Arduino… Ali, depois de ver aqueles códigos, percebi que conseguiria começar a brincar com isso (depois posto algumas coisas que consegui fazer, um deles, sobre como utilizar uma ponte H já está iniciado, só falta finalizar)… Estou inclusive montando um robozinho rádio controlado (criança com brinquedo novo é sempre assim)…

    Esse ano também mudei (novamente) de empresa… Isso acabou me rendendo mais amigos (inclusive de copo) e uma certa maturidade… Pelo fato de estar desenvolvendo as aplicações web sozinho acabei conseguindo adquirir uma maior autonomia (não de trabalhar sozinho, mas de saber tomar decisões por conta própria quando necessário)… Tenho tentado, quando os prazos permitem, utilizar algumas boas práticas que conhecia em teoria mas que ainda não tinha posto em prática… Comecei a brincar com testes unitários e mock objects

    E além de estar participando do grupo do ArduinRio estou participando também do grupo que esta tentando criar um Hackerspace aqui no Rio de Janeiro… E, pelo que tenho visto, parece que dessa vez sai… Seria bem interessante ter um espaço pra trocar uma ideia (sobre os mais variados assuntos) pessoalmente e onde pôr em prática alguns projetos…

    Enfim, esse ano que passou foi bem proveitoso…
    Além de que estou aproveitando para testar o aplicativo do WordPress pra Android (por onde estou finalizando o texto, no ônibus)…

    PS: apesar do post estar sendo publicado agora, eu comecei a escrevê-lo ainda ano possado, apenas não tive tempo para finalizá-lo…


  • Velocidade de produção vs Qualidade de código

    Há alguns meses (desde setembro, pra ser mais exato) mudei de empresa e, depois que cheguei, me avisaram que a equipe de Java seria formada por mim e… É… E eu… rsrs. E ainda pior, o projeto estava com pelo menos 15 dias de atraso… Até aí beleza, nunca vi um projeto de TI em dia mesmo… Mas dessa vez a coisa foi um pouco além do normal… Acabei prezando pela velocidade na escrita do código, até que semana passada me surgiu a seguinte questão: “Quem é que vai fazer manutenção nisso depois?”, e advinhem qual não foi meu espanto quando me lembrei que havia apenas eu na equipe… E aí ércebi que estava apenas escrevendo código atrás de código sem nem ao menos ter alguém pra testar o que eu fazia… E nesse instante me veio a questão à cabeça: “Fazer rápido ou com qualidade e legibilidade?”… Resolvi chutar o balde e mandar o prazo (ainda acho que pra estimar prazos devemos conhecer ao menos a equipe que vai executar o projeto, senão você acaba “executando” o projeto) pro espaço… Vou fazer da forma certa… Vamos lá, rapaz, você já conhece todas as boas práticas (desacoplamento, coesão, testes, códigos bem organizados, testes unitários, porquê não pôr em prática? Então resolvi fazer da forma certa, até o momento não tive muitos problemas (exceto pra entender como funcionava o EasyMock – ainda não tinha utilizado nenhum framework pra criação de objetos Mock)…

    Como eu já utilizava o Maven pra gerenciamento de dependências externas e automação do build da aplicação, não tive que mudar muita coisa na forma com que trabalhava, uma vez que ele executa todos os testes que se encontram na pasta “/src/test/java” do projeto e caso algum não passe ele interrompe o processo e avisa quais testes não passaram…


  • Hello World of Android

    Pois é, depois de um longo sumiço cá estou eu outra vez (deu muito trabalho remover as teias e as respectivas aranhas)…

    Venho hoje para falar do meu primeiro contato com o mundo de desenvolvimento para a plataforma Android (preciso explicar ou citar referências?)… Como não sou muito paciente com esse negócio de começar do mais básico (primeiro um Hello World, depois a gente incrementa um detalhezinho aqui, depois outro ali), ainda mais quando é algo que eu já conheço (ou, nesse caso, que eu conheço algo MUITO semelhante, que é o Java)… Daí resolvi definir um projeto e ir implementando ele aos poucos, conforme meu tempo permitisse… Aí surgiu a questão de definir o que fazer… Pensei em várias coisas, até que me veio algo que me pareceu bem desafiador (apenas não muito útil, mas bem desafiador – no meu ponto de vista, claro)… Alguém já ouviu falar de um pessoal que, antigamente, costumava marcar locais em que havia sinal WI-FI com desenhos no chão? Não sei se isso realmente acontecia (ou se acontecia aqui no Brasil), mas o negócio foi que eu resolvi criar algo que te permita demarcar locais com algum símbolo ou texto, semelhante ao que esse pessoal fazia, mas de forma virtual… De forma que quando você estivesse próximo ao local marcado você visse essa marca… Taí, gostei da idéia, simples mas com requintes desafiadores (na verdade a única parte que me parece complexa é a parte de utilizar o GPS, descobrir como capturar um desenho feito pelo usuário na tela do aparelho e aprender a utilizar o SQLite – nunca fui com a cara dele, mas infelizmente tenho que usar)…

    No momento tenho apenas uma definição do projeto e alguns códigos de teste.

    Vamos ao que consegui até o momento…

    Aqui está um rascunho de como buscar a localização atual:

    public class HelloMapsApiActivity extends Activity {
    
    	private static final String LOG_TAG = "ELDIOSANTOS";
    	private static Location localAnterior = null;
    
    	private LocationManager locationManager;
    	private LocationListener locationListener;
    	private String provider;
    
    	/** Called when the activity is first created. */
    	@Override
    	public void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.main);
    
    		setListener();
    	}
    
    	private void setListener() {
    		// Buscar o gerenciador de serviços de localização do aparelho.
    		locationManager = (LocationManager) this
    				.getSystemService(Context.LOCATION_SERVICE);
    
    		// Criar um listener que vai executar o que queremos quando alguma
    		//		alteração (relativa a localização) ocorrer.
    		locationListener = new LocationListener() {
    			
    			// Foi encontrada uma nova localização.
    			public void onLocationChanged(Location location) {
    				tratarLocalizacao(location);
    			}
    
    			// Mudança de status do seu provider.
    			public void onStatusChanged(String provider, int status,
    					Bundle extras) {
    				debug("Provider (" + provider + "): " + status);
    			}
    
    			// Quando o provider estiver habilitado.
    			public void onProviderEnabled(String provider) {
    				debug("Provider (" + provider + "): enabled");
    			}
    
    			// Quando o provider for desabilitado.
    			public void onProviderDisabled(String provider) {
    				addTextToView("Provider (" + provider + "): disabled");
    			}
    		};
    
    		// Aqui criamos uma "Criteria" para buscar o nosso provedor de localização
    		Criteria crit = new Criteria();
    
    		// O critério a ser utilizado, neste caso, para a busca é a precisão
    		crit.setAccuracy(Criteria.ACCURACY_FINE);
    
    		List<String> providers = locationManager.getProviders(crit, true);
    
    		// Caso não seja encontrado um utilizamos o provedor de rede mesmo
    		if (providers.isEmpty()) {
    			provider = LocationManager.NETWORK_PROVIDER;
    		} else {
    			provider = providers.get(0);
    		}
    
    		// Registrando nosso listener.
    		locationManager.requestLocationUpdates(provider, 0, 0, locationListener);
    	}
    
    	private void tratarLocalizacao(Location location) {
    
    		try {
    			for (String obj : location.getExtras().keySet()) {
    				debug(obj.toString() + ": " + location.getExtras().get(obj));
    			}
    
    			TrataDados trat = new TrataDados();
    
    			trat.salvaLocation(location, getApplicationContext());
    
    
    			StringBuffer string = new StringBuffer(location.getProvider())
    				.append(location.getProvider()).append(" ")
    
    				.append(location.getLatitude()).append("/")
    				.append(location.getLongitude())
    
    				.append("nAcurácia: ").append(location.getAccuracy());
    
    			if (localAnterior != null) {
    				string.append("nDistância: ").append(
    						location.distanceTo(localAnterior));
    			}
    
    			string.append("n++++++++++++++++++++++++");
    
    			Log.d(LOG_TAG, string.toString());
    
    			localAnterior = location;
    
    		} catch (Exception e) {
    			addTextToView("Erro ao executar ação...");
    			addTextToView(e.getMessage());
    			Log.e(LOG_TAG, "Erro ao executar tarefa...", e);
    		}
    	}
    }

    Pois é, até o momento foi o que consegui, assim que conseguir algo mais interessante volto a postar aqui…

     


  • Mini servidor de arquivos e impressão

    Como a ideia surgiu:

    Há um ou dois meses atrás vi uma caixinha no DealExtreme (olha ela aqui) que me interessou… Imagina só uma caixinha que poderia servir como cliente Bit Torrent standalone (sem precisar de um computador ligado) que salvaria o download em algum dispositivo USB plugado a ela ou também poderia usar como servidor de impressão (imagina só, tenho uma impressora em casa – não tive tempo$ para comprar uma de rede – e dois notebooks – um meu e um da minha mãe – em casa, é chato ter que toda vez que for imprimir algo ter que levar o note até a impressora)… Beleza, vou comprar! Até que percebo que ela só tem 1 (apenas uma) USB… Poxa, acho que vou precisar de 2 dessas… Mas ainda assim fiquei decepcionado… Foi aí que todo a ideia começou a se modelar (às vezes elas parecem ter vida própria)… Lembrei-me que tinha uma placa mão e um processador (um Celerom D 2.8GHz), um pente de 1GB de RAM… Acho que não vou mais comprar a caixinha, pensei eu… E logo em seguida me veio uma frase à cabeça: “Quest acepted!” (com direito a musiquinha de RPG de nintendinho rsrs)…

    The saga begins:
    Meu mini-servidor precisaria ter pelo menos os mesmos recursos que a caixinha: acesso via FTP, interface do Torrent via browser e coisas assim… Pensei em incluir algumas outras coisas, afinal seria um desperdício de processamento (mesmo pra um Celeron – não gosto da família Celeron, ams quando comprei precisava de um computador urgentemente e não tinha tempo$ pra um decente)… Porquê não incluir, além do servidor de arquivos e de impressão e o cliente torrent, um Tomcat pra desenvolvimento (algo pra utilizar antes de subir minhas aplicações para Zion – antes que perguntem, Zion é o nome que demos a este servidor, ideia minha)… Então percebi que não tinha HD algum funcionando, meus dois últimos foram pro espaço por causa da placa mão do computador da sala (hoje percebo que se ele não tivesse falecido teria voado varanda abaixo – relaxem, a varando fica apenas 5 metros acima do nível da rua)… E apenas 1GB de memória DDR (isso mesmo, gente, DDR1) não seriam o suficiente…
    Mas antes de comprar o que faltava, resolvi ter uma noção do trabalho que teria… Primeiro fui atrás de uma solução para o cliente de torrent com interface web, consegui encontrar isso aqui: WebTorrent… Apesar de que vou pesquisar se o uTorrent funciona via prompt (afinal ele já possui uma interface web nativa)…
    Ainda não tive tempo de comprar o HD e as memórias que precisarei para começar, mas assim que iniciar o trabalho vou postando aqui o que e como fiz, além de que vou mostrar o resultado final (e dizer se o trabalho valeu a pena)…
    To be continued…

  • Ausência prolongada

    Pois é, mais uma vez abandono este humilde alfarrábio digital, mas desta vez eu tive motivos sérios (?) para isto, estava finalizando (finalmente) meu Trabalho de Conclusão de Curso, vulgo TCC… Inclusive, houve uma alteração que pediram que, caso consiga implementar, merece vir pra cá… Se conseguir posto mais detalhes sobre o que é… rsrs.

    Tentarei voltar a postar ao menos um artigo por semana novamente assim que finalizar as modificações que foram pedidas…

    No mais, nada mais…


  • Carregando plugins em tempo de execução em Java

    Há algum tempo (mais especificamente quando comecei a achar que já sabia o básico de Java e que precisava tentar algo realmente difícil, mesmo que não tão útil), lá pelos idos de 2006 ou 2007, resolvi que iria desenvolver um cliente de email, com algumas das funcionalidades úteis do que eu conhecia na época (Outlook, alguém conhece?)… Comecei a estudar os protocolos SMTP e POP3 (não conhecia o javax.mail) e comecei a brincar com Sockets (isso, se não tem algo mais simples vai na marra mesmo. Damn it!! I’ll do it by myself!!), como tive que fazer com o HTTP pra um trabalho de faculdade certa vez… Depois de algum tempo brincando com isso foi que conheci a javax.mail (para mais informações: javax.mail) e resolvi poupar massa cinzenta…

    Mas enfim, o que me motivou a escrever este post não foi exatamente isso, mas sim o fato de que eu queria que o software tivesse algum diferencial, algo que o tornasse útil pelo menos pra mim (se outras pessoas também gostassem seria lucro), daí pensei em fazer o software e depois criar plugins para ele (só não fazia a menor idéia de como faria isso, mas faria)… Cheguei a implementar as classes base, mas acabei deixando de lado pois não sabia como implementar o sistema de plugins (além da falta de tempo e do excesso de preguiça que também colaboraram rsrs)…

    Essa semana estava pensando em como seria pra montar esse esquema para adicionar plugins sem precisar modificar meu código inicial… Depois de pensar, cheguei na seguinte mecânica (a nível de usuário ainda, não de desenvolvedor): tenho uma aplicação em uma pasta, incluo uma pasta chamada plugins e incluo o jar do plugin ali.
    Beleza, já sei como fazer isso “por fora”… Mas como eu faço isso dentro do sistema pra incluir isso em tempo de execussão? Pensei inclusive em criar um launcher (uma aplicação/script que é acionada e que fica responsável por chamar a minha aplicação) que buscaria todos esses arquivos jar presentes na pasta de plugins e incluindo na opção “-cp” do comando “java” (para saber mais: java command line) que chamaria a aplicação de verdade… Seria uma solução simples, mas algo nela não me agradou…
    Depois de um tempo pensando no assunto me lembrei de um exemplo que vi de um CustomClassloader, onde poderíamos manipular algo no carregamento ou no comportamento das classes no sistema (acho que foi um exemplo de Programação Orientada a Aspecto). Comecei a pesquisa à partir daí…
    Pesquisando um pouquinho (no nosso grande amigo Google), consegui encontrar uma solução para carregar os arquivos dinamicamente sem muitos problemas.

    Simplificando um pouco, foi algo meio assim:

    public class JarClassLoader extends URLClassLoader {
    
    	public JarClassLoader(URL[] urls) {
    		super(urls);
    	}
    
    	public void addFile(URL path) throws MalformedURLException {
    		super.addURL(path);
    	}
    }

    Antes de mais nada, o método addURL do URLClassLoader é protected, de modo que não poderia acessar em um URLClassLoader normal.

    Daí pra buscar todos os arquivos foi simplesmente utilizar um objeto File mais ou menos assim:

    	URL[] urls = {};
    
    	JarClassLoader cl = new JarClasLoader(urls);
    
    	File pluginFolder = new File("./plugin");
    
    	File[] jars = pluginFolder.lisFiles();
    
    	for(File f: jars){
    		cl.addFile(f.toURI().toURL());
    	}

    E assim carregamos todos os arquivos na pasta plugins, a não ser que hajam outros arquivos na pasta além dos seus jars, o que te obrigaria a implementar um FileFilter ou um FileNameFilter e passá-lo como parâmetro no método listFiles do objeto pluginFolder.

    Depois disso eu já posso buscar minha classe com um loadClass do meu ClassLoader, passando como parâmetro o nome completo da classe que deseja carregar (devemos lembrar que não tem como carregar duas classes com mesmo full qualified name – ou, de forma mais simples, mesmo nome e mesmo pacote – ou carregar novamente uma com mesmos nome e pacote de algo que já foi carregado por um ClassLoader pai).

    	Class clazz = cl.loadClass(fullQualifiedClassName);

    E com isso, agora já posso ter uma instância dessa classe.

    	Object obj = clazz.newInstance();

    Beleza, já tenho como criar um objeto com o nome completo da classe… Mas e se eu não souber o nome dela de antemão? Ou mesmo que soubesse, como um Object me vai ser útil se eu não sei como utilizá-lo?
    Pensei em algumas soluções. E em todas (ou quase todas, afinal largar isso tudo de lado e ir tomar um sorvete chegou a passar pela minha cabeça) elas havia a presença de uma interface. Por isso criei uma interface (InterfaceTeste).

    public interface InterfaceTeste {
    	public abstract String getString();
    }

    Agora só falta a parte do nome da classe… Pensei em incluir um XML no jar, mas aí lembrei da minha ânsia de vômito quando vejo que tenho que criar um XML de configuração de alguma ferramenta (tudo isso graças ao finado Struts 1)… Facilitaria o trabalho e aumentaria o desempenho pelo fato de não precisar fazer uma busca no arquivo. Pensei em dar essa opção, o que não precisaria de mais nada, apenas utilizar o método getResourceAsStream do ClassLoader passando o nome do arquivo como poarâmetro e parsear o XML…

    Parti para a parte (eu sei, ficou estranho, mas enfim, prossigamos) da busca das classes contidas no jar…
    Mais um tempo no Google me rendeu bons frutos (como sempre)… Vi uma citação ao pacote java.util.jar… Olhada no Javadoc (acho que sejs válido uma olhadinha aqui: javadoc java.util.jar) encontrei algumas classes que tinham potencial, mas no fim utilizei apenas o JarFile e o JarEntry (que derivam de ZipFile e ZipEntry, respectivamente). Com isso consegui listar todos os arquivos contidos no jar (que não deixa de ser um zip).

    	JarFile jarFile = new JarFile(jarFile);
    	Enumeration jarEntrys = jarFile.entries();

    Cada um desses JarEntry representa um arquivo dentro do seu jar. Utilizando o método getName deste objeto para obter o nome do arquivo (que consiste no caminho e o nome do arquivo – algo como ‘br/net/eldiosantos/MinhaClasse.class’). De posse dele, e sabendo que os pacotes, em Java, representam pastas, podemos pegar esse nome, verificar se termina por ‘.class’ e, se verdadeiro, retirar o ‘.class’ e substituir a ‘/’ por ‘.’. Assim já temos o nome das classes presentes no pacote.

    E, por último, como eu iria trabalhar com uma interface (afinal nem todas as classes precisam implementar minha interface), eu verifico as classes uma a uma pra ver se alguma delas implementa a interface que quero.

    	Class clazz = cl.loadClass(nameClass);
    	Class[] interfaces = clazz.getInterfaces();

    E assim resolvemos o problema…

     

    Em breve disponibilizo minha implementação aqui (assim que achar que esta bom o suficiente).

     


  • Reflections: como funciona e pra que serve?

    Há algum tempo atrás tive um problema interessante com meu projeto final da faculdade (que perdura até os dias atuais) que era o fato de a especificação dizer que deveria ser possível fazer a pesquisa no banco de dados preenchendo o conjunto de campos/atributos que quisesse (incluindo nenhum)… Agora imaginem a cena: você com um sistema cujo diagrama de classes de modelo contém pelo menos umas 25 classes, com uma média de uns 8 a 13 atributos cada, tendo que criar um método getByExemplo no Dao de cada uma delas, verificando cada atributo se foi preenchido e acrescentando… Mesmo utilizando Hibernate/JPA, seria algo meio (isso, só meio) pé no saco (não sei, depois da reforma ortográfica continua com hífem?) e eu não estava nem um pouco afim de fazer isso dessa forma…

    Até que lembrei-me da API de Reflections do Java… Resumindo a história, a API de Reflections serve pra você manipular classes e objetos sem necessariamente saber quem ou o que é… Ela te permite descobrir métodos, atributos, modificadores de acesso, entre outras coisas (note neste momento que quando faltam argumentos/palavras as pessoas utilizam um “entre outras coisas” ou o famoso “etcétera”)…

    Mas como a coisa funciona?

    A assinatura do método seria algo do tipo:

    	public List<T> getByExemplo(T obj)

    Primeiro precisamos obter a classe com a qual vamos trabalhar:

    	Class<?> clazz = obj.getClass();

    E à partir daí podemos começar a brincar…

    No meu caso eu simplesmente peguei a lista de atributos e fui percorrendo-os e verificando os modificadores, nomes e valores… Algo mais ou menos assim:

    package net.eldiosantos.testes.classloaders;
    
    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.print(" " + 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));
    			}
    		}
    	}
    }

    Pois é, tentei incluir esse exemplo no site do anterior mas ele não permite o uso do método setAccessible. Por isso tive que adaptar o código que fiz rodar lá, mas na essência é a mesma coisa…

    Segue o link da execução do código: http://ideone.com/zV7U5


  • Passagem de parâmetros em Java

    Aqui vai um testezinho legal para aquecer…

    Alguém sabe como o Java trabalha com a passagem de parâmetros? Eu, desde meu início nessas paragens, sempre ouvi falar que tipos primitivos eram passados por valor e objetos eram passados por referência… O código abaixo testa exatamente isso…

    
    public class ClasseTeste {
    
    	public static void main(String[] args) {
    		String parametro = "parametro ";
    		String retorno = testeParametro(parametro);
    
    		System.out.println(retorno == parametro);
    
    		System.out.println(parametro);
    
    		System.out.println(retorno);
    	}
    
    	public static String testeParametro(String parametro) {
    		parametro += "[modificado]";
    
    		return parametro;
    	}
    }
    
    

    Link do resultado: http://ideone.com/XjcdR

    O link acima exibe o resultado do código supracitado…

    Voltemos ao assunto… Depois de verificar o resultado e “Googlar” um pouquinho, descobri que os objetos são realmente passados por referência, porém se você fizer a referência local (variável dentro do método) apontar para outra instância (não se esqueça, em Java o tipo String é um objeto imutável, se você o modifica ele simplesmente abandona o objeto atual e cria um novo com o novo valor) você não altera a referência externa (variável do método main passada como parâmetro)… Ou seja, esta referência externa não pode ser modificada… Só o que podemos modificar é o conteúdo do objeto (atributos) e não o objeto ao qual a variável aponta…