M. *_*awy 5 java code-generation dynamic names
假设我需要生成变量来保存用户的一些输入(我不知道它们有多少).如果不使用Array,ArrayList(和其他类型的列表和地图),可我的代码生成(可以说)String有相似的名字(变量X倍String var001,String var002,String var003,等)?如果是,请提供示例代码.
如果你真的想做类似的事情,可以通过使用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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
以下是我实施并帮助我轻松修复解决方案的方法,没有太多障碍。
// 创建数组List
List accountList = new ArrayList();
for(int k=0;k < counter;k++){
accountList.add(k, (String)flowCtx.getValueAt("transitId"+m));
}
Run Code Online (Sandbox Code Playgroud)
迭代循环并将对象添加到带有索引的数组列表中。
//在运行时借助索引检索对象
String a = accountList.get(i));
Run Code Online (Sandbox Code Playgroud)