This is a followup to this question about java private constructors.
Suppose I have the following class:
class Foo<T> { private T arg; private Foo(T t) { // private! this.arg = t; } @Override public String toString() { return "My argument is: " + arg; } }
How would I construct a new Foo("hello")
using reflection?
ANSWER
Based on jtahlborn's answer, the following works:
public class Example { public static void main(final String[] args) throws Exception { Constructor<Foo> constructor; constructor = Foo.class.getDeclaredConstructor(Object.class); constructor.setAccessible(true); Foo<String> foo = constructor.newInstance("arg1"); System.out.println(foo); } }
Using private constructor, prevents the creation of the instances of that class. If a class contains only private constructor without parameter, then it prevents the automatic generation of default constructor.
Yes, we can access the private constructor or instantiate a class with private constructor. The java reflection API and the singleton design pattern has heavily utilized concept to access to private constructor.
Class. getDeclaredConstructor() can be used to obtain the constructor object for the private constructor of the class. The parameter for this method is a Class object array that contains the formal parameter types of the constructor.
Yes, we can declare a constructor as private. If we declare a constructor as private we are not able to create an object of a class. We can use this private constructor in the Singleton Design Pattern.
Make sure you use getDeclaredConstructors
when getting the constructor and set its accessibility to true since its private.
Something like this should work.
Constructor<Foo> constructor= (Constructor<Foo>) Foo.class.getDeclaredConstructors()[0]; constructor.setAccessible(true); Foo obj = constructor.newInstance("foo"); System.out.println(obj);
Update
If you want to make use of getDeclaredConstructor, pass Object.class as an argument which translates to a generic T.
Class fooClazz = Class.forName("path.to.package.Foo"); Constructor<Foo> constructor = fooClazz.getDeclaredConstructor(Object.class); constructor.setAccessible(true); Foo obj = constructor.newInstance("foo"); System.out.println(obj);
you would need to get the class, find the constructor which takes a single argument with the lower bound of T (in this case Object), force the constructor to be accessible (using the setAccessible
method), and finally invoke it with the desired argument.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With