Is there away to generate Variables' names dynamically in Java?

后端 未结 10 2379
醉酒成梦
醉酒成梦 2020-11-28 14:46

Let\'s say that I need to generate variables to hold some input from the user (I don\'t know how many they are). Without using Array, ArrayList (an

10条回答
  •  被撕碎了的回忆
    2020-11-28 15:25

    If you really want to do something like that, you can do it through bytecode generation using ASM or some other library.

    Here is code that will generate a class named "foo.bar.ClassWithFields" that contains fields "var0" to "var99". Of course there is no way other than reflection to access those fields, because they don't exist at compile time and Java is a statically typed language.

    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, "", "()V", null, null);
                mv.visitCode();
                mv.visitVarInsn(ALOAD, 0);
                mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()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);
            }
        }
    }
    

提交回复
热议问题