How to create and initialize dynamic variables...

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • krishna81m
    New Member
    • Oct 2007
    • 25

    How to create and initialize dynamic variables...

    How to create dynamic variables as follows

    for(...)
    {
    Run This( "int var" + i = i;);
    }

    to be able to create and initialize var1 = 1; var2 = 2;

    I was able to do this in a couple of scientific programming languages without any problem..

    Help please..
  • BigDaddyLH
    Recognized Expert Top Contributor
    • Dec 2007
    • 1216

    #2
    Easily done with a Map.

    Comment

    • chaarmann
      Recognized Expert Contributor
      • Nov 2007
      • 785

      #3
      You should do it with arrays/maps instead of using a couple of loose variables.

      Defining "int[] vars" is better than using "var1, var2, var3 etc."

      But if you still want, despite all experience:
      you can define "public static Integer var1, var2 etc" as member of a class and then use "reflection " to modify the values of this class in a loop.

      Code:
      Class c = Class.forName("myClass");
      for (i=1; ....)
      {
        Field f = c.getField("var" + i);
        f.setInt(this, i);
      }
      (code not yet tested, but I hope you get the idea.)

      Comment

      • BigDaddyLH
        Recognized Expert Top Contributor
        • Dec 2007
        • 1216

        #4
        Originally posted by chaarmann
        You should do it with arrays/maps instead of using a couple of loose variables.

        Defining "int[] vars" is better than using "var1, var2, var3 etc."

        But if you still want, despite all experience:
        you can define "public static Integer var1, var2 etc" as member of a class and then use "reflection " to modify the values of this class in a loop.

        Code:
        Class c = Class.forName("myClass");
        for (i=1; ....)
        {
          Field f = c.getField("var" + i);
          f.setInt(this, i);
        }
        (code not yet tested, but I hope you get the idea.)
        The idea I get is that this would be a spectacularly bad idea!

        Comment

        • krishna81m
          New Member
          • Oct 2007
          • 25

          #5
          Code:
             1. Class c = Class.forName("myClass");
             2. for (i=1; ....)
             3. {
             4. Field f = c.getField("var" + i);
             5. f.setInt(this, i);
             6. }
          This is exactly what I thought of initially. The problem with this code really is that you need to know the field names, type of variables that you are setting aprior as in f.setInt(this,i )
          and I have to initialize different number and type of fields.

          So I thought I could create a string equivalent

          List<someObject Name> myList;
          myList.add(some ObjectName(var1 , var2, var3,....))


          Let me first explain my actual problem in detail first:

          I have a dynamically created query that is run on the database and we have the result set columns which can be used to initialize a known object. These objects (type not known) with constructors have to be populated dynamically. Essentially a list of these objects must be passed to some table in a jsp for display purposes. The jsp page dynamic tag libraries only accepts bean/objects.

          As an awkward solution to this, we tried a genericBean object with 10 string fields in it and hence the object has a constructor with 10 fields, a maximum number of fields we might have to display in the jsp table. As different queries return different number of columns (converted to string equivalents), the remaining fields in the constructor are set as empty strings. At the jsp page, we control how many columns we want to display in the jsp from this list of objects.

          Is there a solution to this problem?

          Comment

          • krishna81m
            New Member
            • Oct 2007
            • 25

            #6
            [CODE=java]package org.struts.ets. utility;

            import java.lang.refle ct.Constructor;
            import java.lang.refle ct.InvocationTa rgetException;
            import java.util.Array List;
            import java.util.List;

            import org.struts.bean .GenericDAOBean ;

            public class DynamicObjectCr eation
            {
            public static void main(String... args)
            {
            Constructor[] ctors = GenericDAOBean. class.getDeclar edConstructors( );
            Constructor ctor = null;
            for (int i = 0; i < ctors.length; i++)
            {
            ctor = ctors[i];
            if (ctor.getGeneri cParameterTypes ().length == 2)
            break;
            }

            try
            {
            ctor.setAccessi ble(true);

            // This is what is created dynamically and passed to the
            // action class
            Object myObj1 = ctor.newInstanc e("A", "B");
            Object myObj2 = ctor.newInstanc e("C", "D");
            List<Object> myObjList = new ArrayList<Objec t>();
            myObjList.add(m yObj1);
            myObjList.add(m yObj2);

            // the action class casts into the object type it needs
            GenericDAOBean myGenObj = (GenericDAOBean ) myObjList.get(0 ); // myObj1
            // Field f = c.getClass().ge tDeclaredField( "var1");
            // f.setAccessible (true);
            // System.out.prin tln("output: " + f.get(c).toStri ng());
            System.out.prin tln("output: " + myGenObj.getVar 1());

            // passing a list of these generic objects
            List<GenericDAO Bean> myGenObjList = new ArrayList<Gener icDAOBean>();
            myGenObjList = (myGenObjList)m yObjList;

            // production code should handle these exceptions more gracefully
            } catch (InstantiationE xception x)
            {
            x.printStackTra ce();
            } catch (InvocationTarg etException x)
            {
            x.printStackTra ce();
            } catch (IllegalAccessE xception x)
            {
            x.printStackTra ce();
            }
            }
            }[/CODE]

            See that this is where I have the problem,

            [CODE=java]List<GenericDAO Bean> myGenObjList = new ArrayList<Gener icDAOBean>();
            // or
            // List<GenericDAO Bean> myGenObjList = null;

            myGenObjList = (myGenObjList)m yObjList;[/CODE]

            It says myGenObjList cannot be resolved to a type
            Last edited by Ganon11; Feb 21 '08, 08:13 PM. Reason: Please use the [CODE] tags provided.

            Comment

            • BigDaddyLH
              Recognized Expert Top Contributor
              • Dec 2007
              • 1216

              #7
              [CODE=Java]myGenObjList = (myGenObjList)m yObjList;[/CODE]

              For casting, what goes in the parentheses must be a type, not a variable.

              Comment

              • chaarmann
                Recognized Expert Contributor
                • Nov 2007
                • 785

                #8
                ...
                The problem with this code really is that you need to know the field names, type of variables that you are setting aprior as in f.setInt(this,i )
                and I have to initialize different number and type of fields.
                ...
                There is no need to "know" the field names in advance. You can just enumerate them.
                For example:
                Code:
                Class c = Class.forName("myClass");
                Field[] f = c.getFields();
                for (int i=0; i < f.length; i++)
                {
                 ...
                Just look in the JDK description for all methods of class "Class".
                You can get all information about the class there, also skope, field types, methods, method parameters etc.

                But if you only want to pass data, then you can just declare the method parameter as "Object" and pass it. Then you can test with "instanceOf " which type it is. But that also means you must do some inboxing/outboxing for primitive types. Then for example you cannot store an integer as "int", but must convert it to "Integer" before passing.

                Second suggestion: if you already have converted all table column values to "String", then you can use "Properties " to store them in a manner of key=variableNam e, value=variableV alue. No need to hardcode a fixed size array as what you described in your example.
                If you have more than one record(row) returned from database, you can use "Vector" of "Properties " and pass/return that as argument/returnValue to your functions.

                Comment

                • djamshed
                  New Member
                  • Mar 2008
                  • 1

                  #9
                  Here is a very hard-coded alternative to your problem:
                  1) Create an interface with value setter
                  Code:
                       public interface RowWithColumnValues {
                               void setColumnValue(int columnId, String value);
                      }
                  2) Hard-code part: create classes that implement the interface above with exactly 1"escalating " variable and extending the "previous" variable's class:

                  Code:
                   public class RowWithColumn1 implements RowWithColumnValues {
                  
                        public String column1;
                  
                       public void setColumnValue(int columnId, String value)
                       {
                             if(columnId == 1)
                             column1= value;
                       }
                  }
                  
                  
                  public class RowWithColumn2 extends RowWithColumn1 {
                  
                        public String column2;
                  
                        public void setColumnValue(int columnId, String value)
                        {
                              if(columnId == 2)
                                   column2 = value;
                              else
                                    super.setColumnValue(columnId, value);
                        }
                  }
                  
                  
                  public class RowWithColumn3 extends RowWithColumn2{
                  
                        public String column3;
                  
                        public void setColumnValue(int columnId, String value)
                        {
                              if(columnId == 3)
                                    column3 = value;
                              else
                                    super.setColumnValue(columnId, value);
                        }
                  }
                  
                  
                  //etc, yes, you have to make as much classes as your possible maximum number of variables
                  3) Create a Factory that will return you the proper class with variables
                  Code:
                  public RowWithColumnValues getRowObject(int numberOfColumns)
                  {
                           RowWithNodes rowObject = null;
                           switch(numberOfColumns)
                           {
                                    case 1: rowObject= new RowWithColumn1(); break;
                                    case 2: rowObject= new RowWithColumn2(); break;
                                    case 3: rowObject= new RowWithColumn3(); break;
                                    //....
                                    case 100: rowObject= new RowWithColumn100(); break;
                                    default: rowObject= new RowWithColumn100(); break;
                           }
                  
                           return rowObject;
                  }


                  Now, you can use this as:

                  Code:
                  RowWithColumnValues row= new RowWithColumnValues().getRowObject(numOfColumns);
                  // set column values
                  for(int i = 1; i < numOfColumns+1; i++)
                  {
                          row.setColumnValue(i, rs.getString(i));
                  }
                  rows.add(row);
                  A bit more clearer explanation is given at http://djamshed.blogspot.com/2008/03...r-dynamic.html

                  Comment

                  • krishna81m
                    New Member
                    • Oct 2007
                    • 25

                    #10
                    Thanks Jamshed,

                    I am looking into it and also going through your blog entry. Will get back to you soon.

                    -Cheers
                    Krishna

                    Comment

                    Working...