[英]Java: accessing private constructor with type parameters
This is a followup to this question about java private constructors . 这是关于java私有构造函数的这个问题的后续内容 。
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? 我如何使用反射构造一个
new Foo("hello")
?
ANSWER 回答
Based on jtahlborn's answer , the following works: 根据jtahlborn的回答 ,以下作品:
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);
}
}
Make sure you use getDeclaredConstructors
when getting the constructor and set its accessibility to true since its private. 确保在获取构造函数时使用
getDeclaredConstructors
,并将其可访问性设置为true,因为它是私有的。
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. 如果要使用getDeclaredConstructor,请将Object.class作为参数传递,转换为通用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);
你需要获取类,找到带有T的下限的单个参数的构造函数(在本例中为Object),强制构造函数可访问(使用setAccessible
方法),最后使用所需的参数调用它。
Well in case if private constructor does not take any argument then we fetch problem while creating new instance, in this case after setAccessible true we can't create object. 好吧,如果私有构造函数不接受任何参数,那么我们在创建新实例时获取问题,在这种情况下,在setAccessible为true后我们无法创建对象。 Even
construct.newInstance(null);
甚至
construct.newInstance(null);
won't create object for no argument constructor. 不会为没有参数构造函数创建对象。
can we create object of below 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 the object of above 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: Example 2: "Eager Initialization" and "Singleton Violation by reflection" of my blog: http://sanjaymadnani.wordpress.com/2014/04/14/singleton-design-pattern-in-java/ 您可以参考:示例2:我的博客中的“Eager Initialization”和“Singleton Violation by reflection”: http : //sanjaymadnani.wordpress.com/2014/04/14/singleton-design-pattern-in-java/
As @ArtB said you could use dp4j.com , if you know the constructor you want to use at compile-time . 正如@ArtB所说,你可以使用dp4j.com , 如果你知道你想在编译时使用的构造函数 。 On the project homepage there's an example of just that, accessing a Singleton constructor.
在项目主页上有一个例子,访问Singleton构造函数。
Instead of JUnit's @Test annotate the method in which to inject the Reflection with @Reflect: 而不是JUnit的@Test注释用@Reflect注入Reflection的方法:
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 the reflection generated code use -Averbose=true argument as in this answer . 要查看反射生成的代码,请使用-Averbose = true参数, 如此答案中所示 。
如果Junit测试类(在测试文件夹中)具有与实际类相同的包名,那么从Junit测试用例中,我们可以调用所有私有方法进行测试,而不需要任何额外的库,如dp4j。
At first I was getting NoSuchMethodException using reflection. 起初我使用反射得到NoSuchMethodException。
Use this: 用这个:
Constructor<TestClass> constructor= (Constructor<TestClass>) TestClass.class.getDeclaredConstructors()[0];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.