Eu sei acessar por reflection declarações da minha classe (métodos, variáveis, etc…)
Mas tenho um caso aqui em que quero acessar variáveis que estão dentro de um método. Ai dá erro dizendo que não encontrou a variável. Vejam o erro:
java.lang.NoSuchFieldException: pHistimp1
Tudo acontece dentro do meu método geracaoDemonstrativoLucroPrejuizo(), as variáveis estão declaradas ai dentro e eu tb estou executando o comando reflection ai dentro.
Estou tentando assim:
[code]int vCodigo = 0;
try {
vCodigo = (Integer)this.getClass().getField(“pHistimp1”).get(this);
} catch (Exception e) {
e.printStackTrace();
}
[/code]
Não funciona, dá o erro que eu já falei.
Então tentei especificar o método em que eu estou, tentei da seguinte forma:
[code]int vCodigo = 0;
try {
Method metodo = this.getClass().getDeclaredMethod(“geracaoDemonstrativoLucroPrejuizo”,new Class[] {});
Uma variável local não pode ser obtida ou acessada via reflection, até porque ela pode ser “optimized out” (ou seja, removida ou transformada devido à otimização).
É uma variável local mesmo que você está tentando obter?
“Alguma forma” com certeza existe! Afinal qdo fazemos o debug da aplicação, é possível ler/alterar variaveis dentro de um método… correto?
Mas tbm desconheço esse recurso seja na reflection ou GCLib… com certeza isso demanda uma boa pesquisa!
Infelizmente, variáveis locais e parâmetros não podem ser acessados corretamente via reflection.
Quanto às primeiras eu digo que é realmente complicado obter a variável correta “por nome”, já que escopos são difíceis de especificar corretamente, e envolveriam a colaboração do compilador.
Quanto aos segundos, eu acho que é uma falha da API de reflection.
Haviam prometido que iriam incluir parâmetros no reflection (por exemplo, listar os nomes dos parâmetros de um método via reflection), mas por enquanto você só consegue saber os tipos de cada parâmetro de um método, mas não seus nomes. Isso provavelmente não será mudado no Java 7, conforme você pode ver em: http://download.java.net/jdk7/docs/api/java/lang/reflect/Method.html
[quote=Giulliano]Renata (desculpe a curiosidade) mas eu não vejo uma situação em que é preciso usar reflections dentro de um método com uma varíavel de método… :/[/quote]Leu meu pensamento
Acho que ela quer criar uma rotina que pode listar ou modificar uma variável local ou de instância, passando apenas o nome. Só que isso é um pouco inviável no caso de uma variável local, até por causa dos problemas de escopo.
Não é possível recuperar as variáveis em um método, por causa do escopo delas. O tempo de vida é muito curto, e provavelmente, esse erro que você apresentou, ocorre devido ao fato de que essas variáveis não existem mais.
Tenho uma situação idiota aqui, que ocorre dentro de um método, em que o nome de algumas variáveis são bem parecidos, suponhamos por ex que seja assim: valor1, valor2, valor3,… valor5 e cod1, cod2,… cod6
O processamento que tenho que fazer para elas será sempre o mesmo, então eu fiz um for básico, de 1 a 6 (seguindo meu exemplo acima de nomes de variáveis), onde eu fazia o mesmo processamento pra todas as vars. Porém fui desbancada pelo fato da Reflection não pegar variáveis.
Eu já faço isso em outros casos, casos em que por ex, na tela tenho caixas de texto com nomes parecidos, etc… mas ai são variáveis públicas.
Tenho a impressão que você está sofrendo sem necessidade…
Eu teria feito dessa maneira:
Object[] codigos = {cod1, cod2, cod3, cod4, cod5, cod6}
Object[] valores = {valor1, valor2, valor3, valor4, valor5, valor6}
// Coloquei como Object porque não sei o tipo
for (int i = 0; i < codigos.length; i++) {
//Processa
}
Tá certo que vai precisar digitar o nome de cada variável na declaração do array, mas nem se compara a repetir todo o código.
E também tem vantagens sobre a solução com Reflection: o código fica mais “limpo” e um pouco mais seguro contra erros pois é verificado na compilação.
[quote=gomesrod]Tenho a impressão que você está sofrendo sem necessidade…
Eu teria feito dessa maneira:
Object[] codigos = {cod1, cod2, cod3, cod4, cod5, cod6}
Object[] valores = {valor1, valor2, valor3, valor4, valor5, valor6}
// Coloquei como Object porque não sei o tipo
for (int i = 0; i < codigos.length; i++) {
//Processa
}
Tá certo que vai precisar digitar o nome de cada variável na declaração do array, mas nem se compara a repetir todo o código.
E também tem vantagens sobre a solução com Reflection: o código fica mais “limpo” e um pouco mais seguro contra erros pois é verificado na compilação.[/quote]
Não, não estou sofrendo… eu já resolvi, como eu falei num post dias atrás. Alias, fiz algo bem parecido com o que vc fez.
Como eu falei no outro post, eu só tentei usar via Reflection, não funcionou e eu queria entender pq não estava funcionando. Agora eu aprendi que é pq Reflection não acessa vars privadas. Foi para entender o motivo de não funcionar… eu segui fazendo de outra forma e pronto.
Se as varíaveis locais do método são de mesmo typo, talvez utilizare um array[] o equivalente e depois utilizar o FOR :
O processamento que fazer para elas será sempre o mesmo ?
gomesrod, tivemos a mesma idea mas o tempo para a minha messagem chegar de Paris au Brasil você fez o post antes de mim :-)
Sim sim… você já disse que tinha achado uma solução, só estava mesmo metendo o nariz onde não fui chamado
Mas já que estamos falando no assunto, tem uma pequena regra que costumo seguir: Usar Reflection é para frameworks e classes de infraestrutura; para as classes “normais” (negócio, telas, etc) sempre existem alternativas mais simples e seguras.
[quote=JxtaNode]gomesrod, tivemos a mesma idea mas o tempo para a minha messagem chegar de Paris au Brasil você fez o post antes de mim [/quote] É, ouvi falar que os aeroportos estão um caos