Acessando variáveis através de strings

5 respostas
T

Olá!
Tenho uma classe de constantes do tipo:

public class Constantes { public static final int CONSTANTE1 = 1; public static final int CONSTANTE2 = 2; }

E tenho um arquivo xml:

<constante>CONSTANTE1</constante>
<constante>CONSTANTE2</constante>

Imagino que vou pegar o nome das constantes por String, logo terei:

String str1 = "CONSTANTE1";
String str2 = "CONSTANTE2";

Uma última coisa: a classe de constantes não é controlada por mim, e está em constante mudança, logo gostaria de uma solução o mais “solta” possível.

A pergunta é: como usar essas strings para acessar as constantes da minha classe de constante em runtime? Há alguma maneira?

5 Respostas

P

acho que o que vc procura é reflection. aqui no guj tem um tutorial bem interessante sobre o reflection.

ViniGodoy

Carregue suas constantes num mapa, que relaciona o nome da constante ao seu valor.
Nada pode ser mais fácil e flexível do que isso.

A sintaxe vai ser um pouco mais chata de usar:
String valor = Constantes.get("CONSTANTE1");

Você pode prover métodos úteis como:
int valor = Constantes.getInt("CONSTANTE1");

A classe constantes ficaria assim:

public class Constantes { 
    private Map&lt;String, String&gt; constantes = new HashMap&lt;String, String&gt;();

    public static String get(String name) {
       return constantes.get(name);
    }

    public static Map&lt;String, String&gt; asMap() {
       return Collections.unmodifiableMap(constantes);
    }

    public static int getInt(String name) {
       return Integer.parseInt(get(name));
    }

    public static int getDougle(String name) {
       return Double.parseDouble(get(name));
    }
}

Também não custa dar uma olhada na classe Properties, que já faz esse tipo de coisa.

Reflection está entre as piores soluções possíveis para o seu caso.

T

Obrigado, ViniGodoy, a sua solução parece a que vai funcionar, já que estou usando J2ME e não tenho reflection. Porém, vai dar um bom trabalho popular o Map, já que a minha classe de constantes é beeeem grande, e provavelmente vai ficar bem travada, pois toda vez que eu criar uma constante nova, vou ter que mudar o código, a não ser que tenha uma idéia melhor.

palmadias, a idéia de reflection é perfeita! Fiz um teste aqui com J2SE e é exatamente o que procuro! Porém, com J2ME tenho acesso bem limitado a isso. Consigo no máximo usar o forname e conseguir a instância da classe, mas não tenho acesso a métodos e fields.

Ainda busco um meio termo a isso =)

ViniGodoy

Mudar o código? Por que? Você pode adicionar os objetos ao mapa dinamicamente… você pode fazer essa classe carregar as constantes do xml diretamente. E bem grande quanto? Duvido muito que seja grande o suficiente para você sequer perceber qualquer problema de performance. Se houver um problema, vai ser com o xml, não com o map.

Novamente, volto a afirmar que reflection não é o caminho. Pelo menos, não para essa situação. Reflection gera um código complexo, inseguro e geralmente difícil de manter.

T

ViniGodoy, obrigado novamente pela ajuda. Talvez tenha me expressado mal. Já tenho uma classe com as constantes definidas, e já tenho um XML que utiliza essas constantes pelo nome. O que eu queria fazer é ler o nome da variável do xml, acessar a classe de constantes e conseguir o valor da mesma. Logo, o que eu pensei com a sua solução seria:

* Fazer um código de loading (provavelmente seria bem hard coded, já que eu teria que pegar o nome da constante, o valor dela, e adicionar ao hash, uma por uma). Não sei como fazer isso dinamicamente. O que eu pensei seria algo do tipo:
public static final int CONSTANTE1 = 1;
public static final int CONSTANTE2 = 1;

Map<String, String> map = new HashMap<String, String>();
map.put("CONSTANTE1", "1");
map.put("CONSTANTE2", "2");
* Em tempo de execução, ler do xml o nome da variável, acessar o valor dela no hash e utilizá-lo no meu código (essa é a parte fácil).

E em razão do código grande, digo ter que fazer a primeira parte com cada constante do arquivo, e ter que atualizar toda vez que uma constante nova é criada. A respeito de performance, também não acho que vá dificultar muito.

Quando disse que o reflection parecia ser o melhor caminho, acho que seria mais simples ler do xml, e já procurar logo de cara pelo valor da constante. É um código simples (2 ou 3 linhas já resolvo isso), e não preciso me preocupar com ter que carregar todas as constantes para um hash.

Agradeço qualquer idéia =)

Criado 9 de dezembro de 2008
Ultima resposta 9 de dez. de 2008
Respostas 5
Participantes 3