Java: accessing a private constructor with type parameters

This is a continuation of this question about private java 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 build 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); } } 
+49
java reflection private constructor
Apr 12 2018-11-11T00:
source share
6 answers

you will need to get a class, find a constructor that takes one argument with a lower bound T (in this case Object), force the constructor to be available (using the setAccessible method), and finally invoke with the desired argument.

+24
Apr 12 2018-11-11T00:
source share

Make sure you use getDeclaredConstructors when getting the constructor and set its accessibility to true with 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 use getDeclaredConstructor, pass Object.class as an argument, which translates to general 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); 
+27
Apr 12 '11 at 3:11
source share

Well, if the private constructor does not accept any arguments, we get a problem when creating a new instance, in this case after setAccessible true we cannot create an object. Even construct.newInstance(null); will not create an object without an argument constructor.

we can create an object below the code using reflection:

 public class Singleton { private static Singleton instance = new Singleton(); /* private constructor */ private Singleton() {} public static Singleton getDefaultInstance() { return instance; } } 

Yes, we can create an object above the class.

 // reflection concept to get constructor of a Singleton class. Constructor<Singleton> constructor = Singleton.class.getDeclaredConstructor(); // change the accessibility of constructor for outside a class object creation. constructor.setAccessible(true); // creates object of a class as constructor is accessible now. Singleton secondOb = constructor.newInstance(); // close the accessibility of a constructor. constructor.setAccessible(false); 

You can refer to: Example 2: “Bright initialization” and “Singleton reflection violation” on my blog: http://sanjaymadnani.wordpress.com/2014/04/14/singleton-design-pattern-in-java/

+8
Apr 11 '14 at 21:05
source share

Like @ArtB said you can use dp4j.com if you know the constructor you want to use at compile time . On the main page of the project there is an example of exactly this, access to the Singleton constructor.

Instead of JUnit @Test, annotate the method in which you want to enter Reflection using @Reflect:

 public class Example { @com.dp4j.Reflect public static void main(final String[] args){ Foo<String> foo = new Foo("hello"); System.out.println(foo); } } 

To see that the generated reflection code used the -Averbose = true argument, as in this answer .

+3
Apr 13 '11 at 7:25
source share

If the Junit test class (in the test folder) has the same package name as for the Actual Class, then from the Junit Test we can call all the private methods for testing without any additional library, such as dp4j.

+2
Jun 06 '16 at 17:37
source share

There is a library for JUnit ( dp4j ) that automatically inserts code to access private methods. This may be helpful.

+1
Apr 12 '11 at 3:20
source share



All Articles