Zuweisen von Variablen mit dynamischen Namen in Java

96

Ich möchte eine Reihe von Variablen in Java wie folgt zuweisen:

int n1,n2,n3;

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

Wie kann ich dies in Java erreichen?

Ashish Anand
quelle
1
Könnten Sie bitte Ihre Frage klären?
Eng.Fouad
4
Sie müssen dies für lokale Variablen tun? Warum nicht Array-Elemente?
Ray Toal
@ Eng.Fouad: Ich möchte dynamisch auf Variablen mit ihrem Namen zugreifen.
Ashish Anand
@ Ashish Anand meinst du stackoverflow.com/questions/6629995/…
mKorbel

Antworten:

111

So machen Sie es in Java nicht. In Java gibt es keine dynamischen Variablen. Java-Variablen müssen im Quellcode 1 deklariert werden .

Je nachdem, was Sie erreichen möchten, sollten Sie ein Array verwenden, a Listoder a Map; z.B

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);
}

Mit Reflection können Sie dynamisch auf Variablen verweisen , die im Quellcode deklariert wurden. Dies funktioniert jedoch nur für Variablen, die Klassenmitglieder sind (dh statische Felder und Instanzfelder). Es funktioniert nicht für lokale Variablen. Siehe @ fyrs "schnelles und schmutziges" Beispiel.

Es ist jedoch eine schlechte Idee, solche Dinge in Java unnötig zu tun. Es ist ineffizient, der Code ist komplizierter und da Sie sich auf die Laufzeitprüfung verlassen, ist er anfälliger. Und das sind keine "Variablen mit dynamischen Namen". Es wird besser als dynamischer Zugriff auf Variablen mit statischen Namen beschrieben.


1 - Diese Aussage ist etwas ungenau. Wenn Sie BCEL oder ASM verwenden, können Sie die Variablen in der Bytecode-Datei "deklarieren". Aber tu es nicht! Auf diese Weise liegt der Wahnsinn!

Stephen C.
quelle
1
Vielen Dank, habe bekommen, wonach ich gesucht habe. Der letzte Teil (Map <String, Integer>).
Ashish Anand
1
Es sollte beachtet werden, dass selbst wenn es möglich wäre, es nicht etwas sein sollte, was Sie tatsächlich tun würden. Sie gewinnen nichts davon; Sie verlieren tatsächlich die Lesbarkeit. Wenn Sie sie verknüpfen möchten, verwenden Sie Map<String, T>stattdessen a und beginnen Sie nicht, mit Ihrem tatsächlichen Code herumzuspielen.
Jeroen Vannevel
2
@JeroenVannevel - Das habe ich mit "Wahnsinn" gemeint :-)
Stephen C
35

Wenn Sie auf die Variablen in irgendeiner Art von Dynamik zugreifen möchten, können Sie Reflektion verwenden. Reflection funktioniert jedoch nicht für lokale Variablen. Sie gilt nur für Klassenattribute.

Ein grobes, schnelles und schmutziges Beispiel ist:

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);
        }
    }
}

Sie müssen diesen Code auf verschiedene Weise verbessern. Dies ist nur ein Beispiel. Dies wird auch nicht als guter Code angesehen.

fyr
quelle
3
Hervorragend geeignet, wenn Sie den Android-Sensor event.values ​​[] in eine Reihe von Variablen konvertieren müssen. event.values ​​[] kann eine Länge von 1 bis 6 haben und es ist praktisch, es konvertieren zu lassen, in meinem Fall für ein Array-freies JSON-Marshalling.
Farshid T
12

Was Sie brauchen, heißt Array. Ich wollte folgenden Code schreiben:

int[] n = new int[4];

for(int i=1;i<4;i++)
{
    n[i] = 5;
}
AlexR
quelle
1
Ich möchte keine Arrays verwenden. Ich möchte je nach Bedingung dynamisch auf die Variablen (n1, n2, n3) zugreifen.
Ashish Anand
10

Sie sollten Listoder arraystattdessen verwenden

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

Oder

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

Oder noch besser

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

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

Dynamische Variablennamen in Java
gibt es nicht.

In Ihrem Fall können Sie Array verwenden:

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

(name, value)Verwenden Sie für allgemeinere PaareMap<>

Op De Cirkel
quelle
4

Versuchen Sie Folgendes:

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

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

quelle
4

Das tust du nicht. Das Beste, was Sie tun können, ist, mit Maps zu arbeiten, um es zu simulieren, oder Ihre eigenen Objekte zu definieren, mit denen Sie sich befassen möchten.

Everton
quelle