Can I use Class.newInstance() with constructor arguments?
Asked Answered
E

9

272

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?

Extranuclear answered 24/10, 2008 at 17:48 Comment(0)
D
239
MyClass.class.getDeclaredConstructor(String.class).newInstance("HERESMYARG");

or

obj.getClass().getDeclaredConstructor(String.class).newInstance("HERESMYARG");
Diller answered 24/10, 2008 at 17:52 Comment(4)
Just clarifying - getDeclaredConstructor is not a static method, you have to call it on the instance of the Class for your specific class.Grodno
Seems like the answer is "no" for Java 1.1Extrovert
I have public constructor with List<String> parameters. Can't get it by getDeclaredConstructor, but with getConstructor works fine. Do you know why?Ileanaileane
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 parametersResupinate
B
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.

Burleson answered 24/10, 2008 at 17:51 Comment(3)
Answer doesn't say how you pass the args, or show an example. It's just a guess.Hatchel
Should it be getDeclaredConstructor (singular) ?Ablation
@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!Shoestring
S
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);
Sycosis answered 8/6, 2014 at 19:15 Comment(0)
O
19

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

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

Olen answered 24/10, 2008 at 20:43 Comment(0)
S
9

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

Stuffy answered 24/10, 2008 at 17:51 Comment(0)
V
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
Vern answered 29/10, 2016 at 10:40 Comment(0)
A
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;
    }
}
Antitrust answered 2/7, 2013 at 14:56 Comment(0)
B
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

Berdichev answered 24/4, 2014 at 11:31 Comment(0)
K
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();
    }
}
Knighthead answered 24/11, 2022 at 7:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.