Creating objects from strings

87 views Asked by At

So I've read in some data from an XML:

String arg1Value;
String arg2Value;
String arg2TypeAsString;
String arg1TypeAsString;

and I want to create an object: ObjectType(arg1Type, arg2Type);

I'm trying this:

(ObjectType) Class.forName(arg1TypeAsString).getConstructor(arg1Type.class, arg2Type.class).newInstance(arg1Value, arg2Value)

But this gives me a noSuchMethodException: ObjectType.<init>(arg1Type, arg2Type)

Note that I'm trying to create different objects but they all extend from ObjectType and all their arguments extend from arg1Type and arg2Type respectively.

2

There are 2 answers

0
Ulvon On

Given the specifications are a bit vague (no actual code), try the followings:

  1. Make sure your constructor does not have private, protected or default package modifier, if so, use getDeclaredConstructor() instead
  2. Define a default constructor for ObjectType class
  3. Split your statement on multiple lines:

    Class<ObjectType> otClass = (ObjectType) class.forName(arg1TypeAsString);
    Constructor<ObjectType> otConstructor = otClass.getConstructor(arg1Type.class, arg2Type.class);
    ObjectType ot = otConstructor.newInstance(arg1Value, arg2Value);
    
1
Filip Bulovic On

My initial assumption was that newInstance should be called with array of objects. This is not correct, see comment below. Then likely reason is that you are passing primitive type to newInstance for example int instead of Integer. Naturally creating array of Objects will eliminate such possibility. Finally I managed to replicate error message by removing constructor from my target class so it couldn't be found

java.lang.NoSuchMethodException: Foo.<init>(java.lang.String, java.lang.String)

Please take a look at all those exceptions which implementation throws. Please create your ObjectType compile it and place it in classpath so it could be found. Here is my implementation of method returning Object which you can cast to desired type

static Object createInstance(String clsName, String ctorType1, String ctorVal1, String ctorType2, String ctorVal2)
      throws ClassNotFoundException, NoSuchMethodException, InstantiationException, 
      IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    return Class.forName(clsName).getConstructor(Class.forName(ctorType1), Class.forName(ctorType2))
        .newInstance(new Object[]{ctorVal1, ctorVal2});
  }

It is tested and works. Quite few exceptions to catch. You may want to adjust parameter types so they fit your design requirements. This is my test class

public class Foo {
  public Foo(String in, String out){}
}