Java:使用类型参数访问私有构造函数

dsg*_*dsg 67 java reflection constructor private

这是关于java私有构造函数的这个问题的后续内容.

假设我有以下课程:

class Foo<T>
{
    private T arg;
    private Foo(T t) {
        // private!
        this.arg = t;
    }   

    @Override
    public String toString() {
        return "My argument is: " + arg;
    }   
}
Run Code Online (Sandbox Code Playgroud)

我如何构建new Foo("hello")使用反射?

回答

根据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);
    }   
}
Run Code Online (Sandbox Code Playgroud)

Moh*_*our 46

确保getDeclaredConstructors在获取构造函数时使用,并将其可访问性设置为true,因为它是私有的.

这样的事情应该有效.

Constructor<Foo> constructor= (Constructor<Foo>) Foo.class.getDeclaredConstructors()[0];
constructor.setAccessible(true); 
Foo obj = constructor.newInstance("foo"); 
System.out.println(obj);
Run Code Online (Sandbox Code Playgroud)

更新

如果要使用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);
Run Code Online (Sandbox Code Playgroud)


jta*_*orn 28

你需要获取类,找到带有T的下限的单个参数的构造函数(在本例中为Object),强制构造函数可访问(使用该setAccessible方法),最后使用所需的参数调用它.

  • 本文可能有所帮助:http://dunwood.blogspot.com/2004/05/instantiate-java-class-that-has.html (6认同)

San*_*ani 9

好吧,如果私有构造函数不接受任何参数,那么我们在创建新实例时获取问题,在这种情况下,在setAccessible之后,我们无法创建对象.甚至construct.newInstance(null);不会为没有参数的构造函数创建对象.

我们可以使用反射创建下面代码的对象:

public class Singleton {

    private static Singleton instance = new Singleton();

    /* private constructor */
    private Singleton() {}

    public static Singleton getDefaultInstance() {
        return instance;
    }
}
Run Code Online (Sandbox Code Playgroud)

是的,我们可以创建上面的类的对象.

// 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);
Run Code Online (Sandbox Code Playgroud)

您可以参考:示例2:我的博客中的"Eager Initialization"和"Singleton Violation by reflection":http://sanjaymadnani.wordpress.com/2014/04/14/singleton-design-pattern-in-java/