Предположим, что мне нужно сгенерировать переменные, чтобы удерживать некоторые данные от пользователя (я не знаю, сколько они). Без использования Array
, ArrayList
(и другие виды списков и карт) мой код может генерировать (скажем) String
переменные X раз с именами типа (String var001
, String var002
, String var003
и т. Д.)? Если да, укажите пример кода.Есть ли возможность динамически генерировать имена переменных в Java?
ответ
Ниже приводится способ, которым я реализовал и помог мне легко решить мое решение без особых проблем.
// Создание списка массива
List accountList = new ArrayList();
for(int k=0;k < counter;k++){
accountList.add(k, (String)flowCtx.getValueAt("transitId"+m));
}
итерация цикла и добавление объектов в ArrayList с индексом.
// Получение объекта во время выполнения с помощью индекса
String a = accountList.get(i));
Что такое flowCtx здесь? – Yatin
Вы имеете в виду вы хотите создать переменные с именами
var0, var1, var2 и использовать их в вашем коде.
В чем разница при использовании уага [0], уаг [1], вара [2], .....
НО
Вы можете создать класс Java динамически во время выполнения, которое реализует интерфейс, который вы используете в своем обычном коде. Затем вы компилируете этот класс с помощью компилятора (например, Janino), а затем загружаете класс во время выполнения. Чем вы создали класс динамически.
Но мне интересно, нужно ли это для вашего использования.
EDIT
Я не в настоящее время, для которого USECASE вы используете эти параметры, но динамические аргументы, которые вы можете использовать в Java, как этот example from here
// 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>();
Для записи это возможно на PHP. См. «Переменные переменные» в руководстве. –
Извините, я не вижу никаких PHP-тег в этом вопросе ... –
Именование переменных, как что выглядит очень 1980-иш. Значение предпроектированного программирования. Итак, если вы когда-либо создавали программное обеспечение для жизни - НЕ ДЕЛАЙТЕ ЭТО.
Но так как это, кажется, домашнее задание ...
Когда мы говорим о имени переменной в Java, мы имеем в виду то, что компилируется. В отличие от некоторых языков сценариев нет простого способа сделать это в Java.
Таким образом, вы либо используете компилируемый класс среды выполнения, как Маркус Лаусберг.
Или вы обманываете и используете Java Scripting API и используете языки сценариев. Таким образом, вы можете создавать код (в String) во время выполнения.
Java Scripting API очень интересен :) Спасибо за новую информацию! –
Я думаю, что вы можете сгенерировать Java-класс во время выполнения или, возможно, использовать какой-то движок сценария, такой как Beanshell, чтобы сгенерировать переменные, вы даже можете построить класс по его байт-коду. Но я не вижу, как вы будете использовать эти переменные в своем коде, вы также должны создать код для работы с этими переменными или использовать отражение для этого ...
Наивное решение:
создать класс со всеми переменными из var000 в var999 с геттером для каждого ... но это на самом деле не динамически!
Без использования массива, 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"
EDIT
Похоже, внутренне это будет использовать карты :) То же самое с файлом свойств, Preferences API, или DOM деревьев (они с использованием векторов). Поэтому, если ваш профессор настолько придирчив, используйте файлы.
Спасибо за информацию :) –
Я еще не видел этого ответа, поэтому я поеду за ним. Напишите программу, которая просто выписывает исходный код Java. Большинство из них могут быть шаблоном, и у вас будет только цикл, в котором будет записываться столько переменных типа «строка UserString003», сколько вы хотите.
Да, это ужасно. Но, как вы сказали, это проблема концептуальных проблем для домашней работы, так как никто не ошибается в этом для «хорошего» кода, это может решить проблему.
Если вы действительно хотите сделать что-то подобное, вы можете сделать это через генерацию байт-кода, используя ASM или другую библиотеку.
Вот код, который будет генерировать класс с именем «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);
}
}
}
Некоторые комментарии к коду действительно помогут :) спасибо! –
Использует ASM библиотека для создания класса - массив байтов находится в том же формате, что и файлы .class, которые производит компилятор Java, а затем загружает его в JVM. пользовательский загрузчик классов. ASM работает на уровне байт-кода Java (аналогично ассемблеру), поэтому, чтобы понять вышеприведенный код, вам сначала нужно изучить некоторый байт-код Java (документация ASM хороша для этого: http://download.forge.objectweb.org/asm/ ASM-guide.pdf). Некоторые другие библиотеки манипулирования байт-кодами могут быть проще в использовании, чем ASM, потому что они более высокого уровня, чем чистый байт-код. Я думаю, что Джавассист - одна из таких библиотек. –
Похоже, ваш профессор PHP смещенной на функцию (Variable variables), так что он имел в виду, если это было возможно в Java.
Я лично не думаю, что это возможно, а не так, как вы предлагаете. Что можно сделать, так это создание классов во время выполнения, используя такие инструменты, как Javassist, чтобы создать более мощный механизм отражения. Таким образом, вы можете создать класс с переменными, которые вы хотите (строка1, строка2 и т. Д.) Во время выполнения.
Однако не забывайте, что Variable variables - очень плохая техника, которая приводит к неправильному коду. Это может быть полезно в очень немногих случаях, но я действительно не рекомендую его.
Это очень странно запрос ... что вы имеете в виду - «не знаю, сколько есть»? А когда будешь знать? Во время выполнения? Во всяком случае, это действительно выглядит как работа для класса коллекции. Почему вы не можете их использовать? Не могли бы вы рассказать нам больше о вашей проблеме? –
Я знаю, что это странный запрос, но это сложная проблема, которую наш профессор ставит на стол. Поэтому я больше заинтересован в возможности делать это независимо от его удобства использования! Единственный трюк вокруг этого, что обнаружила моя группа, - это то, что «Маркус Лаусберг» уже предложил в отношении этой проблемы ... так и есть ли другой способ? –
Надеюсь, ваш профессор не прочитает переполнение стека! Как его/ее зовут? –