Есть ли способ динамически генерировать имена переменных в Java?

StackOverflow https://stackoverflow.com/questions/1192534

Вопрос

Допустим, мне нужно сгенерировать переменные для хранения некоторого ввода от пользователя (я не знаю, сколько их).Без использования Array, ArrayList (и другие виды списков и карт) может ли мой код генерировать (допустим) String переменные X раз с такими именами , как (String var001, String var002, String var003, и т.д.)?Если да, пожалуйста, предоставьте пример кода.

Это было полезно?

Решение

Ниже приведен способ, который я реализовал и помог мне легко и без особых препятствий исправить мое решение.

// Создание массива List

List accountList = new ArrayList(); 




for(int k=0;k < counter;k++){
        accountList.add(k, (String)flowCtx.getValueAt("transitId"+m));
}

Итерация цикла и добавление объектов в список массивов с индексом.

//Получение объекта во время выполнения с помощью индекса

String a = accountList.get(i));

Другие советы

Если вы Действительно хотите сделать что-то подобное, вы можете сделать это с помощью генерации байт-кода, используя КАК М или какая-то другая библиотека.

Вот код, который создаст класс с именем «foo.bar.ClassWithFields», содержащий поля от «var0» до «var99».Конечно, для доступа к этим полям нет другого способа, кроме отражения, поскольку они не существуют во время компиляции, а Java — статически типизированный язык.

import org.objectweb.asm.*;
import static org.objectweb.asm.Opcodes.*;

import java.lang.reflect.Field;

public class GeneratedFieldsExperiment {

    public static byte[] generateClassWithFields(int fieldCount) throws Exception {
        ClassWriter cw = new ClassWriter(0);
        FieldVisitor fv;
        MethodVisitor mv;
        AnnotationVisitor av0;

        cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, "foo/bar/ClassWithFields", null, "java/lang/Object", null);

        for (int i = 0; i < fieldCount; i++) {
            fv = cw.visitField(ACC_PUBLIC, "var" + i, "Ljava/lang/String;", null, null);
            fv.visitEnd();
        }
        {
            mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
            mv.visitCode();
            mv.visitVarInsn(ALOAD, 0);
            mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
            mv.visitInsn(RETURN);
            mv.visitMaxs(1, 1);
            mv.visitEnd();
        }
        cw.visitEnd();

        return cw.toByteArray();
    }

    public static void main(String[] args) throws Exception {
        MyClassLoader loader = new MyClassLoader();
        Class<?> c = loader.defineClass("foo.bar.ClassWithFields", generateClassWithFields(100));

        System.out.println(c);
        System.out.println("Fields:");
        for (Field field : c.getFields()) {
            System.out.println(field);
        }
    }

    private static class MyClassLoader extends ClassLoader {
        public Class<?> defineClass(String name, byte[] b) {
            return defineClass(name, b, 0, b.length);
        }
    }
}

Без использования Array, ArrayList (и других типов списков и карт)

Создайте файлы с этими именами.Надеюсь, это сработает у вашего профессора.

Или используйте Java Scripting API, упомянутый ранее:

ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");

engine.put("x", "hello"); // you can add any variable here
// print global variable "x"
engine.eval("println(x);");
// the above line prints "hello"

Редактировать

Похоже, что внутренне это будет использовать карты :) То же самое с файлом свойств, API настроек или DOM-деревьями (они используют векторы).Так что, если ваш профессор такой придирчивый, используйте файлы.

Я еще не видел этого ответа, поэтому я пойду на это.Напишите программу, которая просто записывает исходный код Java.Большая часть этого может быть шаблоном, и у вас будет просто цикл, который будет записывать столько переменных типа «строка UserString003», сколько вы захотите.

Да, это ужасно.Но, как вы сказали, это концептуальная проблема для домашнего задания, поэтому, пока никто не примет ее за «хороший» код, это может решить проблему.

Такое именование переменных выглядит в духе 1980-х годов.Значение предобъектно-ориентированного программирования.Так что, если вы когда-нибудь зарабатывали на жизнь созданием программного обеспечения — НЕ ДЕЛАЙТЕ ЭТОГО.

Но так как это похоже на домашнее задание...

Когда мы говорим об именованной переменной в Java, мы имеем в виду что-то скомпилированное.В отличие от некоторых языков сценариев, в Java нет простого способа сделать это.

Итак, либо вы используете скомпилированный класс во время выполнения, как предложил Маркус Лаусберг.
Или вы обманываете и используете API сценариев Java и использовать языки сценариев.Таким образом, вы можете создавать код (в строке) во время выполнения.

Я думаю, вы можете создать класс Java во время выполнения или, возможно, использовать какой-нибудь скриптовый движок, например Биншелл для генерации переменных вы можете даже построить класс по его байт-коду.Но я не понимаю, как вы будете использовать эти переменные в своем коде, вам также необходимо создать код для работы с этими переменными или использовать для этого отражение...

Наивное решение:
создайте класс со всеми переменными от var000 до var999 с геттером для каждой...но это не совсем динамично!

Похоже, ваш профессор предвзято относится к этой функции (Переменные переменные), поэтому он подумал, возможно ли это в Java.

Лично я не думаю, что это возможно, по крайней мере так, как вы предлагаете.Что можно сделать, так это генерировать классы во время выполнения, используя такие инструменты, как Явасист создать более мощный механизм отражения.Таким образом, вы можете создать класс, содержащий нужные вам переменные (строка1, строка2 и т. д.) во время выполнения.

Однако не забывайте, что Переменные переменные это действительно плохой метод, который приводит к плохому коду.Это может быть полезно в очень редких случаях, но я действительно не рекомендую это делать.

Вы имеете в виду, что хотите генерировать переменные с именами

var0, var1, var2 и используйте их в своем коде.

В чем разница, когда вы используете var[0], var[1], var[2] , .....

НО

Вы можете динамически сгенерировать класс Java во время выполнения, который реализует интерфейс, который вы используете в своем обычном коде.Затем вы компилируете этот класс с помощью компилятора (например, Janino), а затем загружаете класс во время выполнения.Чем вы создали класс динамически.

Но мне интересно, необходимо ли это для вашего использования.

Редактировать

Сейчас я не знаю, для какого случая использования вы используете эти параметры, но динамические аргументы вы можете использовать в Java следующим образом пример отсюда

// calculate average
        public static double average( double... numbers )
        {
           double total = 0.0; // initialize total

          // calculate total using the enhanced for statement
          for ( double d : numbers )              
             total += d;                          

          return total / numbers.length;
       } // end method average

Это невозможно, но это идеальный кандидат для использования одной из коллекций Java.

Либо используйте динамически выделенный массив:

String[] arr = new String[RUNTIME_SIZE];

Или список, размер которого может изменяться во время выполнения:

List list = new ArrayList<String>();

Не знаю, правильно ли я вас понял, но если вы пытаетесь использовать для своих переменных динамически создаваемые имена, то да, однозначно — я делаю это так:

// rndRng() creates random numbers in specified range
// this would output dynamically created variable like "name89"
String myDynamicalyCreatedName = "name" + Utils.rndRng(0, 100);
final UberShader $myDynamicalyCreatedName = new UberShader();

Как вы можете видеть, ключевой точкой здесь является знак «$», который по сути говорит: «создать имя переменной из строки, указанной после этого знака», и это, по сути, все — уже несколько лет работает для меня как шарм. Надеюсь, это то, что вы хотели, и это поможет немного решить вашу проблему.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top