Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: accessing private constructor with type parameters

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);     }    } 
like image 914
dsg Avatar asked Apr 12 '11 02:04

dsg


People also ask

Can we have parameters in private constructor?

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.

Can we invoke private constructor in Java?

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.

How a private constructor can be invoked?

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.

Is it possible to have a private constructor write a class and try it out if possible How do you create an instance of it from another class?

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.


2 Answers

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); 
like image 174
Mohamed Mansour Avatar answered Oct 22 '22 04:10

Mohamed Mansour


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.

like image 31
jtahlborn Avatar answered Oct 22 '22 06:10

jtahlborn