6 minutes read

In previous topics, we've learned how to control the fields of an object and invoke methods of a class with reflection. Reflection can also be used to create instances of a class, and in this topic, we will learn how to do so.

Acquiring a constructor

Let's take a look at the following code:

class Item {

    private String name;
    protected int basePrice;

    public Item() {
        this("default");
    }

    public Item(String name) {
        this(name, 0);
    }

    public Item(String name, int basePrice) {
        this.name = name;
        this.basePrice = basePrice;
    }

    public String getName() {
        return name;
    }

    public int getPrice() {
        return (int) (basePrice * getMarkUp());
    }
    
    protected double getMarkUp() {
        double markUp = 0.1;
        // ... connecting to the remote server
        return 1 + markUp;
    }
}

As you can see, there are three constructors and one of them is empty.

In Java, any object must be created by using a constructor. Reflection is no exception: it also requires a constructor to create an instance of a class. Luckily, there is a Constructor class that can do this.

Since a class can have multiple constructors you should pick one first. There are two ways to find a suitable constructor:

1. Calling the getDeclaredConstructors() method from the Class object, and then find a suitable constructor among the existing ones.
2. If you know what types you need to call the constructor with or you need to simply call the constructor without arguments, you can use the getDeclaredConstructor(... ) method and pass objects of the Class type there indicating types of parameters the constructor should have. If you need a constructor without arguments, you don't need to pass anything there.

Once the appropriate constructor has been found, the newInstance(... ) method should be called to create an instance of the class.

There's also another way to create an object by using the newInstance() method on the Class object. For example, to create an object of the Item class, you could write Item.class.newInstance(). Now, this method is deprecated, so it is better to use the other methods discussed above.

Getting constructor parameters

Let's try to use these methods to create an instance of an object. First of all, let's try to output all the constructors and their arguments:

Class itemClass = Item.class;
Constructor[] constructors = itemClass.getDeclaredConstructors();

for (Constructor constructor : constructors) {
    Class[] params = constructor.getParameterTypes();
    System.out.println("Constructor:");
    if (params.length == 0) {
        System.out.println("No params");
        continue;
    }
    for (Class param : params) {
        System.out.println(param);
    }
    System.out.println();
}

As you can see, you need to call getParameterTypes() method to get the constructor arguments.

The code above prints the following:

Constructor:
class java.lang.String
int

Constructor:
class java.lang.String

Constructor:
No params

Everything is as expected. There are three constructors: with zero, one and two arguments.

Creating an instance

Since you must know the types of arguments to create an instance, it is always easier to use the getDeclaredConstructor(... ) method. Below is an example of creating an instance using a constructor with two arguments:

Constructor constructor = itemClass.getDeclaredConstructor(String.class, int.class);
Object instance = constructor.newInstance("orange", 990);

System.out.println(instance.getClass().getSimpleName());

Note that the constructor returns an Object, but in this case, it is actually an Item object. You can verify this by running the code above, and it will output the following:

Item

And calling all the methods of this object will also work. Let's invoke the getName() method.

Method getName = instance.getClass().getDeclaredMethod("getName");
System.out.println(getName.invoke(instance));

And you'll get the following output:

orange

Which indeed means that you are working with the Item object.

Conclusion

From this topic, you should know how to use reflection to create instances: first, we get the constructor object for the class that we want to use; second, we call newInstance() on it, passing the arguments. You may also encounter the newInstance() method with similar functions, which is now deprecated.

76 learners liked this piece of theory. 0 didn't like it. What about you?
Report a typo