简体   繁体   中英

Creating a object from java reflection without knowing the constructor parameters

I am trying to create a collecion of objects using reflection. I have the class name. But at compile time have no idea about the constructor. I used this tutorial.

import java.lang.reflect.*;

  public class constructor2 {
      public constructor2()
      {
      }

  public constructor2(int a, int b)
  {
     System.out.println(
       "a = " + a + " b = " + b);
  }

  public static void main(String args[])
  {
     try {
       Class cls = Class.forName("constructor2");
       Class partypes[] = new Class[2];
        partypes[0] = Integer.TYPE;
        partypes[1] = Integer.TYPE;
        Constructor ct 
          = cls.getConstructor(partypes);
        Object arglist[] = new Object[2];
        arglist[0] = new Integer(37);
        arglist[1] = new Integer(47);
        Object retobj = ct.newInstance(arglist);
     }
     catch (Throwable e) {
        System.err.println(e);
     }
  }

}

Now let's say I don't know abut the parameters of the constructors. (Whether it's a default constructor or two integers). The costructor parameters can change from class to class. I have no idea about the Constructor2 class. But I have the className. So I cant create the "argList" as above. Any idea how I can create a object from constructors then.

I did as follows

Constructor[] brickConstructorsArray = brickClass.getConstructors();
            for (Constructor constructor : brickConstructorsArray) {
                Class[] constructorParams = constructor.getParameterTypes();

                Object argList[] = new Object[constructorParams.length];
                int index = 0;
                for (Class cls : constructorParams) {

                    if (cls.equals(Sprite.class)) {
                        Object spriteOb = foundSprite;
                        argList[index] = spriteOb;
                    } else if (cls.equals(double.class)) {
                        Object dblObj = new Double(0.0);
                        argList[index] = dblObj;
                    }

                    index++;
                }
                brickObject = (Brick) constructor.newInstance(argList);

            }

This would work for costrcutors which will have Sprite or double parameters. To include other possibilities I'd have to create a loooong if else chain. Need help.

Do you really not care what values you're going to pass? You could have a map from each primitive class to a default value of its wrapper type:

// You can make this a static member somewhere
Map<Class<?>, Object> primitiveValues = new HashMap<Class<?>, Object>();
primitiveValues.put(char.class, '\0');
// etc

... and just use null for any non-primitive type. So:

Constructor[] brickConstructorsArray = brickClass.getConstructors();
for (Constructor constructor : brickConstructorsArray) {
    Class[] constructorParams = constructor.getParameterTypes();

    Object argList[] = new Object[constructorParams.length];

    // When you need the index, there's no point in using the enhanced
    // for loop.
    for (int i = 0; i < constructorParams.length; i++) {
        // Fetching the value for any non-primitive type will 
        // give null, which is what we were going to use anyway.
        argList[i] = primitiveValues.get(constructorParams[i]);
    }

    brickObject = (Brick) constructor.newInstance(argList);
}

Of course I'd expect this to fail quite often. After all, if you don't know anything about the constructor you're calling, you have no idea what arguments are going to be valid.

Is this really something you're expecting to find useful?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM