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

36,941

Solution 1

Following is the way that i have implemented and helped me to fix my solution easily without much hurdles.

// Creating the array List

List accountList = new ArrayList(); 




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

Iterating the loop and adding the objects into the arraylist with the index.

//Retrieving the object at run time with the help of the index

String a = accountList.get(i));

Solution 2

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, "<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);
        }
    }
}

Solution 3

Without using Array, ArrayList (and other kind of lists and maps)

Create files with these names. Hope that will work for your professor.

Or use the Java Scripting API mentioned before:

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

Seems like internally this will use Maps :) Same with Properties file, Preferences API, or DOM Trees (they are using Vectors). So if your professor is so picky, use files.

Solution 4

I haven't seen this answered yet, so I'll go for it. Write a program that just writes out Java source code. Most of it could be a template, and you would just have a loop that would write as many "string UserString003" type variables as you want.

Yes, this is horrible. But, as you said, it's a conceptual challenge problem for homework, so as long as no one mistakes this for "good" code, it might solve the issue.

Solution 5

You mean you want to generate variables named

var0, var1, var2 and use them in your code.

What is the difference when you use var[0], var[1], var[2], .....

BUT

You can generate a Java class dynamically at runtime which implements an Interface you are using in your normal code. Then you compile this class using a compiler (For example Janino) and then load the class at runtime. Than you have created a class dynamically.

But i wonder, whether this is necessary for your usecase.

EDIT

I dont now for which usecase you are using this parameters but dynamic arguments you can use in Java like this 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
Share:
36,941
M. A. Kishawy
Author by

M. A. Kishawy

Learning is my Pleasure!

Updated on July 19, 2022

Comments

  • M. A. Kishawy
    M. A. Kishawy almost 2 years

    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 (and other kind of lists and maps) can my code generate (lets say) String variables X times with names like (String var001, String var002, String var003, etc)? If yes, please provide sample code.