Java: newInstance of class that has no default constructor

Solution 1:

Call Class.getConstructor() and then Constructor.newInstance() passing in the appropriate arguments. Sample code:

import java.lang.reflect.*;

public class Test {

    public Test(int x) {
        System.out.println("Constuctor called! x = " + x);
    }

    // Don't just declare "throws Exception" in real code!
    public static void main(String[] args) throws Exception {
        Class<Test> clazz = Test.class;
        Constructor<Test> ctor = clazz.getConstructor(int.class);
        Test instance = ctor.newInstance(5);           
    }
}

Solution 2:

Here is a generic solution that does not require javassist or another bytecode "manipulator". Although, it assumes that constructors are not doing anything else than simply assigning arguments to corresponding fields, so it simply picks the first constructor and creates an instance with default values (i.e. 0 for int, null for Object etc.).

private <T> T instantiate(Class<T> cls, Map<String, ? extends Object> args) throws Exception
{
    // Create instance of the given class
    final Constructor<T> constr = (Constructor<T>) cls.getConstructors()[0];
    final List<Object> params = new ArrayList<Object>();
    for (Class<?> pType : constr.getParameterTypes())
    {
        params.add((pType.isPrimitive()) ? ClassUtils.primitiveToWrapper(pType).newInstance() : null);
    }
    final T instance = constr.newInstance(params.toArray());

    // Set separate fields
    for (Map.Entry<String, ? extends Object> arg : args.entrySet()) {
        Field f = cls.getDeclaredField(arg.getKey());
        f.setAccessible(true);
        f.set(instance, arg.getValue());
    }

    return instance;
}

P.S. Works with Java 1.5+. The solution also assumes there's no SecurityManager manager that could prevent invocation of f.setAccessible(true).