Atribuição de variáveis ​​com nomes dinâmicos em Java

96

Eu gostaria de atribuir um conjunto de variáveis ​​em java da seguinte maneira:

int n1,n2,n3;

for(int i=1;i<4;i++)
{
    n<i> = 5;
}

Como posso fazer isso em Java?

Ashish Anand
fonte
1
Você poderia esclarecer sua dúvida?
Eng.Fouad
4
Você precisa fazer isso para variáveis ​​locais? Por que não elementos do array?
Ray Toal
@ Eng.Fouad: Eu quero acessar variáveis ​​por seus nomes dinamicamente.
Ashish Anand
@Ashish Anand, você está se
referindo a

Respostas:

111

Não é assim que você faz as coisas em Java. Não existem variáveis ​​dinâmicas em Java. As variáveis ​​Java devem ser declaradas no código-fonte 1 .

Dependendo do que você está tentando alcançar, você deve usar um array, a Listou a Map; por exemplo

int n[] = new int[3];
for (int i = 0; i < 3; i++) {
    n[i] = 5;
}

List<Integer> n = new ArrayList<Integer>();
for (int i = 1; i < 4; i++) {
    n.add(5);
}

Map<String, Integer> n = new HashMap<String, Integer>();
for (int i = 1; i < 4; i++) {
    n.put("n" + i, 5);
}

É possível usar a reflexão para referir-se dinamicamente a variáveis ​​que foram declaradas no código-fonte. No entanto, isso funciona para variáveis ​​que são membros da classe (ou seja, campos estáticos e de instância). Não funciona para variáveis ​​locais. Veja o exemplo "rápido e sujo" de @fyr.

No entanto, fazer esse tipo de coisa desnecessariamente em Java é uma má ideia. É ineficiente, o código é mais complicado e, como você depende da verificação do tempo de execução, é mais frágil. E isso não é "variáveis ​​com nomes dinâmicos". É melhor descrito como acesso dinâmico a variáveis ​​com nomes estáticos.


1 - Essa afirmação é ligeiramente imprecisa. Se você usar BCEL ou ASM, você pode "declarar" as variáveis ​​no arquivo bytecode. Mas não faça isso! Essa é a loucura!

Stephen C
fonte
1
Muito obrigado, consegui o que procurava. A última parte (Map <String, integer>).
Ashish Anand
1
Deve-se observar que, mesmo que fosse possível, não deveria ser algo que você realmente faria. Você não ganha nada com isso; você realmente perderá a legibilidade. Se você quiser vinculá-los, use um Map<String, T>, não comece a mexer com seu código real.
Jeroen Vannevel
2
@JeroenVannevel - Isso é o que eu quis dizer com "loucura" :-)
Stephen C
35

Se você quiser acessar as variáveis ​​de algum tipo de dinâmica, você pode usar reflexão. No entanto, o Reflection não funciona para variáveis ​​locais. Só é aplicável para atributos de classe.

Um exemplo rápido e sujo é este:

public class T {
    public Integer n1;
    public Integer n2;
    public Integer n3;

    public void accessAttributes() throws IllegalArgumentException, SecurityException, IllegalAccessException,
            NoSuchFieldException {

        for (int i = 1; i < 4; i++) {
            T.class.getField("n" + i).set(this, 5);
        }
    }
}

Você precisa melhorar este código de várias maneiras, é apenas um exemplo. Isso também não é considerado um bom código.

fyr
fonte
3
Excelente quando você precisa converter o sensor event.values ​​[] do Android em um conjunto de variáveis. event.values ​​[] pode ter um comprimento de 1 a 6 e é útil convertê-lo, no meu caso para um empacotamento json sem array.
Farshid T
12

O que você precisa é um array nomeado. Eu queria escrever o seguinte código:

int[] n = new int[4];

for(int i=1;i<4;i++)
{
    n[i] = 5;
}
AlexR
fonte
1
Não quero usar matrizes. Quero acessar dinamicamente as variáveis ​​(n1, n2, n3) dependendo de alguma condição.
Ashish Anand
10

Você deve usar Listou em arrayvez

List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);

Ou

int[] arr  = new int[10];
arr[0]=1;
arr[1]=2;

Ou melhor ainda

Map<String, Integer> map = new HashMap<String, Integer>();
map.put("n1", 1);
map.put("n2", 2);

//conditionally get 
map.get("n1");
Jigar Joshi
fonte
7

Nomes de variáveis ​​dinâmicas em Java
Não existe tal coisa.

No seu caso, você pode usar array:

int[] n = new int[3];
for() {
 n[i] = 5;
}

Para (name, value)pares mais gerais , useMap<>

Op De Cirkel
fonte
4

Tente desta forma:

    HashMap<String, Integer> hashMap = new HashMap();

    for (int i=1; i<=3; i++) {
        hashMap.put("n" + i, 5);
    }

fonte
4

Você não. A coisa mais próxima que você pode fazer é trabalhar com o Maps para simulá-lo ou definir seus próprios objetos para lidar com eles.

Everton
fonte