Призначення змінних з динамічними іменами в Java


96

Я хотів би призначити набір змінних у Java наступним чином:

int n1,n2,n3;

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

Як я можу досягти цього на Java?


1
Не могли б ви пояснити своє запитання?
Eng.Fouad

4
Вам потрібно це зробити для локальних змінних? Чому б не елементи масиву?
Ray Toal

@ Eng.Fouad: Я хочу динамічно отримувати доступ до змінних за їх іменем.
Ashish Anand

@Ashish Anand ви означаючи stackoverflow.com/questions/6629995 / ...
mKorbel

Відповіді:


111

Це не те, як ви робите речі на Java. У Java немає динамічних змінних. Змінні Java повинні бути оголошені у вихідному коді 1 .

Залежно від того, чого ви намагаєтесь досягти, слід використовувати масив, a Listабо a Map; напр

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

Можна використовувати відображення для динамічного посилання на змінні, які були оголошені у вихідному коді. Однак це лише працює для змінних, які є членами класу (тобто статичні поля та поля екземпляра). Це не працює для локальних змінних. Див. Приклад @ fyr "швидкий і брудний".

Однак робити подібні речі на Java без потреби - погана ідея. Він неефективний, код складніший, і оскільки ви покладаєтесь на перевірку виконання, він більш крихкий. І це не "змінні з динамічними іменами". Це краще описати як динамічний доступ до змінних зі статичними іменами.


1 - Це твердження трохи неточне. Якщо ви використовуєте BCEL або ASM, ви можете "оголосити" змінні у файлі байт-коду. Але не робіть цього! Так лежить божевілля!


1
Подяка багато, отримав те, що я шукав. Остання частина (Map <String, integer>).
Ashish Anand

1
Слід зазначити, що навіть якби це було можливо, це не повинно бути тим, чим ви б насправді займалися. Ви нічого від цього не виграєте; ви фактично втратите читабельність. Якщо ви хочете зв’язати їх, використовуйте Map<String, T>замість цього, не починайте возитися з вашим фактичним кодом.
Jeroen Vannevel

2
@JeroenVannevel - Це те, що я мав на увазі під "божевіллям" :-)
Стівен С

35

Якщо ви хочете отримати доступ до змінних якийсь динамічний, ви можете використовувати відображення. Однак Reflection працює не для локальних змінних. Він застосовується лише для атрибутів класу.

Приблизний швидкий і брудний приклад:

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

Вам потрібно вдосконалити цей код різними способами, це лише приклад. Це також не вважається хорошим кодом.


3
Чудово, коли вам потрібно перетворити сенсор Android event.values ​​[] у набір змінних. event.values ​​[] може мати довжину від 1 до 6, і це зручно для його перетворення, у моєму випадку для маршалінгу json без масиву.
Farshid T,

12

Те, що вам потрібно, називається масивом. Я хотів написати наступний код:

int[] n = new int[4];

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

1
Не хочу використовувати масиви. Я хочу динамічно отримувати доступ до змінних (n1, n2, n3) залежно від якоїсь умови.
Ashish Anand

10

Ви повинні використовувати Listабо arrayзамість цього

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

Або

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

Або навіть краще

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

//conditionally get 
map.get("n1");

7

Динамічні імена змінних в Java
Не існує такого.

У вашому випадку ви можете використовувати масив:

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

Для більш загальних (name, value)пар використовуйтеMap<>


4

Спробуйте так:

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

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

4

Ви цього не робите. Найближче, що ви можете зробити, це робота з Картами для її імітації або визначення власних об’єктів, з якими потрібно мати справу.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.