273

I would like to use Class.newInstance() but the class I am instantiating does not have a nullary constructor. Therefore I need to be able to pass in constructor arguments. Is there a way to do this?

0

9 Answers 9

241
MyClass.class.getDeclaredConstructor(String.class).newInstance("HERESMYARG");

or

obj.getClass().getDeclaredConstructor(String.class).newInstance("HERESMYARG");
Sign up to request clarification or add additional context in comments.

4 Comments

Just clarifying - getDeclaredConstructor is not a static method, you have to call it on the instance of the Class for your specific class.
Seems like the answer is "no" for Java 1.1
I have public constructor with List<String> parameters. Can't get it by getDeclaredConstructor, but with getConstructor works fine. Do you know why?
It should be noted that this requires you to catch a whole slew of exceptions. When I realized there were at least 4, I just threw it in a try/catch block. Also, the arguments to getDeclaredConstructor() are the classes of the constructor parameters
91
myObject.getClass().getDeclaredConstructors(types list).newInstance(args list);

Edit: according to the comments seems like pointing class and method names is not enough for some users. For more info take a look at the documentation for getting constuctor and invoking it.

3 Comments

Answer doesn't say how you pass the args, or show an example. It's just a guess.
Should it be getDeclaredConstructor (singular) ?
@ryvantage is doesn't make it look like a static method as it's all being called on the "myObject" instance. It's just a daisy chain of method calls.Also not sure why this answer was useful to 55 people as it's wrong and the right one is below!
85

Assuming you have the following constructor

class MyClass {
    public MyClass(Long l, String s, int i) {

    }
}

You will need to show you intend to use this constructor like so:

Class classToLoad = MyClass.class;

Class[] cArg = new Class[3]; //Our constructor has 3 arguments
cArg[0] = Long.class; //First argument is of *object* type Long
cArg[1] = String.class; //Second argument is of *object* type String
cArg[2] = int.class; //Third argument is of *primitive* type int

Long l = new Long(88);
String s = "text";
int i = 5;

classToLoad.getDeclaredConstructor(cArg).newInstance(l, s, i);

Comments

19

Do not use Class.newInstance(); see this thread: Why is Class.newInstance() evil?

Like other answers say, use Constructor.newInstance() instead.

Comments

9

You can get other constructors with getConstructor(...).

Comments

8

Follow below steps to call parameterized consturctor.

  1. Get Constructor with parameter types by passing types in Class[] for getDeclaredConstructor method of Class
  2. Create constructor instance by passing values in Object[] for
    newInstance method of Constructor

Example code:

import java.lang.reflect.*;

class NewInstanceWithReflection{
    public NewInstanceWithReflection(){
        System.out.println("Default constructor");
    }
    public NewInstanceWithReflection( String a){
        System.out.println("Constructor :String => "+a);
    }
    public static void main(String args[]) throws Exception {

        NewInstanceWithReflection object = (NewInstanceWithReflection)Class.forName("NewInstanceWithReflection").newInstance();
        Constructor constructor = NewInstanceWithReflection.class.getDeclaredConstructor( new Class[] {String.class});
        NewInstanceWithReflection object1 = (NewInstanceWithReflection)constructor.newInstance(new Object[]{"StackOverFlow"});

    }
}

output:

java NewInstanceWithReflection
Default constructor
Constructor :String => StackOverFlow

Comments

1

You can use the getDeclaredConstructor method of Class. It expects an array of classes. Here is a tested and working example:

public static JFrame createJFrame(Class c, String name, Component parentComponent)
{
    try
    {
        JFrame frame = (JFrame)c.getDeclaredConstructor(new Class[] {String.class}).newInstance("name");
        if (parentComponent != null)
        {
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
        else
        {
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        }
        frame.setLocationRelativeTo(parentComponent);
        frame.pack();
        frame.setVisible(true);
    }
    catch (InstantiationException instantiationException)
    {
        ExceptionHandler.handleException(instantiationException, parentComponent, Language.messages.get(Language.InstantiationExceptionKey), c.getName());
    }
    catch(NoSuchMethodException noSuchMethodException)
    {
        //ExceptionHandler.handleException(noSuchMethodException, parentComponent, Language.NoSuchMethodExceptionKey, "NamedConstructor");
        ExceptionHandler.handleException(noSuchMethodException, parentComponent, Language.messages.get(Language.NoSuchMethodExceptionKey), "(Constructor or a JFrame method)");
    }
    catch (IllegalAccessException illegalAccessException)
    {
        ExceptionHandler.handleException(illegalAccessException, parentComponent, Language.messages.get(Language.IllegalAccessExceptionKey));
    }
    catch (InvocationTargetException invocationTargetException)
    {
        ExceptionHandler.handleException(invocationTargetException, parentComponent, Language.messages.get(Language.InvocationTargetExceptionKey));
    }
    finally
    {
        return null;
    }
}

Comments

1

I think this is exactly what you want http://da2i.univ-lille1.fr/doc/tutorial-java/reflect/object/arg.html

Although it seems a dead thread, someone might find it useful

Comments

0

This is how I created an instance of Class clazz using a dynamic constructor args list.

final Constructor constructor = clazz.getConstructors()[0];
final int constructorArgsCount = constructor.getParameterCount();
if (constructorArgsCount > 0) {
    final Object[] constructorArgs = new Object[constructorArgsCount];
    int i = 0;
    for (Class parameterClass : constructor.getParameterTypes()) {
        Object dummyParameterValue = getDummyValue(Class.forName(parameterClass.getTypeName()), null);
        constructorArgs[i++] = dummyParameterValue;
    }
    instance = constructor.newInstance(constructorArgs);
} else {
    instance = clazz.newInstance();
}

This is what getDummyValue() method looks like,

private static Object getDummyValue(final Class clazz, final Field field) throws Exception {
    if (int.class.equals(clazz) || Integer.class.equals(clazz)) {
        return DUMMY_INT;
    } else if (String.class.equals(clazz)) {
        return DUMMY_STRING;
    } else if (boolean.class.equals(clazz) || Boolean.class.equals(clazz)) {
        return DUMMY_BOOL;
    } else if (List.class.equals(clazz)) {
        Class fieldClassGeneric = Class.forName(((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0].getTypeName());
        return List.of(getDummyValue(fieldClassGeneric, null));
    } else if (USER_DEFINED_CLASSES.contains(clazz.getSimpleName())) {
        return createClassInstance(clazz);
    } else {
         throw new Exception("Dummy value for class type not defined - " + clazz.getName();
    }
}

Comments