有没有在Java中dynamic生成variables的名称?
假设我需要生成variables来保存用户的input(我不知道他们有多less)。 没有使用Array
, ArrayList
(和其他types的列表和地图),我的代码可以生成(让我们说) String
variablesX倍与名称像( String var001
, String var002
, String var003
等)? 如果是,请提供示例代码。
以下是我已经实施的方式,并帮助我轻松解决我的解决scheme,没有太多的障碍。
//创build数组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));
如果你真的想这样做,你可以通过使用ASM或其他库生成字节码来完成。
这里是代码,它将生成一个名为“foo.bar.ClassWithFields”的类,其中包含“var0”到“var99”字段。 当然,除了reflection之外,没有办法访问这些字段,因为它们在编译时不存在,Java是静态types的语言。
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(以及其他types的列表和地图)
用这些名字创build文件。 希望能为你的教授工作。
或者使用前面提到的Java脚本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树(他们正在使用vector)。 所以,如果你的教授如此挑剔,使用文件。
像这样的命名variables看起来非常1980年。 意义是面向对象的编程。 所以如果你为了生活而build立软件 – 不要这样做。
但是,因为它似乎是功课…
当我们谈论Java中的命名variables时,我们指的是编译的东西。 与一些脚本语言不同的是,在Java中没有简单的方法。
所以要么使用像Markus Lausberg所build议的运行时编译类。
或者你欺骗并使用Java Scripting API并使用脚本语言。 这样,你可以在运行时创build代码(在string中)。
我想你可以在运行时生成一个Java类,也可以使用像Beanshell这样的脚本引擎来生成variables,甚至可以通过字节码来构build类。 但我不明白你将如何在你的代码中使用这些variables,你还必须创build代码来处理这些variables,或者使用reflection来处理这些variables。
天真的解决scheme:
创build一个从var000到var999所有variables的类,每个类都有一个getter,但是这不是真的dynamic的!
我还没有看到这个答案,所以我会去的。 编写一个只写出Java源代码的程序。 它大部分可以是一个模板,你只要有一个循环,可以根据需要写入尽可能多的“stringUserString003”types的variables。
是的,这太可怕了。 但是,正如你所说,这是一个概念性的作业问题,所以只要没有人把这个错误当做“好”的代码,就可以解决问题。
看起来你的教授是PHP的偏向function( variablesvariables ),所以他想,如果这是可能的Java。
我个人不认为这是可能的,而不是你提出的方式。 可以做的是在运行时生成类,使用像Javassist这样的工具来创build更强大的reflection机制。 所以你可以在运行时创build一个具有你想要的variables(string1,string2等)的类。
但是,不要忘记, variablesvariables是一个非常糟糕的技术,这会导致错误的代码。 这在很less的情况下可能是有用的,但我真的不推荐它。
你的意思是你想要生成名为variables
var0,var1,var2并在代码中使用它们。
当你使用var [0],var [1],var [2],…时有什么区别
但
您可以在运行时dynamic生成一个Java类,它实现了您在普通代码中使用的接口。 然后你使用编译器(例如Janino)编译这个类,然后在运行时加载这个类。 比你创build一个类dynamic。
但是,我想知道,这是否是你的用例所必需的。
编辑
我现在不用哪个用例使用这个参数,但是可以在Java中使用这个dynamic参数,就像这个例子一样
// 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集合之一的完美候选人。
要么使用dynamic分配的数组:
String[] arr = new String[RUNTIME_SIZE];
或者在运行时可以改变它的大小的列表:
List list = new ArrayList<String>();