Java 如何访问类的私有构造函数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2599440/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 09:43:16  来源:igfitidea点击:

How can I access a private constructor of a class?

javaoopconstructorinstance

提问by gmhk

I am a Java developer. In an interview I was asked a question about private constructors:

我是一名 Java 开发人员。在一次采访中,我被问到一个关于私有构造函数的问题:

Can you access a private constructor of a class and instantiate it?

你能访问一个类的私有构造函数并实例化它吗?

I answered 'No' but was wrong.

我回答“不”但错了。

Can you explain why I was wrong and give an example of instantiating an object with a private constructor?

你能解释一下为什么我错了,并举一个用私有构造函数实例化对象的例子吗?

回答by Jon Skeet

  • You can access it within the class itself (e.g. in a public static factory method)
  • If it's a nested class, you can access it from the enclosing class
  • Subject to appropriate permissions, you can access it with reflection
  • 您可以在类本身中访问它(例如在公共静态工厂方法中)
  • 如果是嵌套类,则可以从封闭类中访问它
  • 根据适当的权限,您可以通过反射访问它

It's not really clear if any of these apply though - can you give more information?

不过,尚不清楚这些是否适用 - 您能提供更多信息吗?

回答by tonio

This can be achieved using reflection.

这可以使用反射来实现。

Consider for a class Test, with a private constructor:

考虑一个带有私有构造函数的类 Test:

Constructor<?> constructor  = Test.class.getDeclaredConstructor(Context.class, String[].class);
Assert.assertTrue(Modifier.isPrivate(constructor.getModifiers()));
constructor.setAccessible(true);
Object instance = constructor.newInstance(context, (Object)new String[0]);

回答by jarnbjo

You can of course access the private constructor from other methods or constructors in the same class and its inner classes. Using reflection, you can also use the private constructor elsewhere, provided that the SecurityManager is not preventing you from doing so.

您当然可以从同一类及其内部类中的其他方法或构造函数访问私有构造函数。使用反射,您还可以在其他地方使用私有构造函数,前提是 SecurityManager 不会阻止您这样做。

回答by Joachim Sauer

One way to bypass the restriction is to use reflections:

绕过限制的一种方法是使用反射:

import java.lang.reflect.Constructor;

public class Example {
    public static void main(final String[] args) throws Exception {
        Constructor<Foo> constructor = Foo.class.getDeclaredConstructor();
        constructor.setAccessible(true);
        Foo foo = constructor.newInstance();
        System.out.println(foo);
    }
}

class Foo {
    private Foo() {
        // private!
    }

    @Override
    public String toString() {
        return "I'm a Foo and I'm alright!";
    }
}

回答by 3biga

Look at Singleton pattern. It uses private constructor.

看看单例模式。它使用私有构造函数。

回答by devoured elysium

Well, you can also if there are any other public constructors. Just because the parameterless constructor is private doesn't mean you just can't instantiate the class.

好吧,如果有任何其他公共构造函数,您也可以。仅仅因为无参数构造函数是私有的并不意味着你不能实例化这个类。

回答by gprathour

The very first question that is asked regarding Private Constructors in Interviews is,

面试中关于私有构造函数的第一个问题是,

Can we have Private constructor in a Class?

我们可以在类中有私有构造函数吗?

And sometimes the answer given by the candidate is, No we cannot have private constructors.

有时候选人给出的答案是,不,我们不能有私有构造函数。

So I would like to say, Yes you can have private Constructors in a class.

所以我想说,是的,您可以在类中拥有私有构造函数。

It is no special thing, try to think it this way,

没什么特别的,试着这样想,

Private:anything private can be accessed from within the class only.

私有:任何私有的东西只能从类中访问。

Constructor:a method which has same name as that of class and it is implicitly called when object of the class is created.

构造函数:与类同名的方法,在创建类的对象时隐式调用。

or you can say, to create an object you need to call its constructor, if constructor is not called then object cannot be instantiated.

或者你可以说,要创建一个对象,你需要调用它的构造函数,如果没有调用构造函数,那么对象就不能被实例化。

It means, if we have a private constructor in a class then its objects can be instantiated within the class only. So in simpler words you can say, if the constructor is private then you will not be able to create its objects outside the class.

这意味着,如果我们在类中有一个私有构造函数,那么它的对象只能在类中实例化。所以简单地说,你可以说,如果构造函数是私有的,那么你将无法在类之外创建它的对象。

What's the benefitThis concept can be implemented to achieve singleton object(it means only one object of the class can be created).

有什么好处 实现这个概念可以实现单例对象(即只能创建一个类的对象)。

See the following code,

看下面的代码,

class MyClass{
    private static MyClass obj = new MyClass();

    private MyClass(){

    }

    public static MyClass getObject(){
        return obj;
    }
}
class Main{
    public static void main(String args[]){

        MyClass o = MyClass.getObject();
        //The above statement will return you the one and only object of MyClass


        //MyClass o = new MyClass();
        //Above statement (if compiled) will throw an error that you cannot access the constructor.

    }
}

Now the tricky part, why you were wrong, as already explained in other answers, you can bypass the restriction using Reflection.

现在棘手的部分,为什么你错了,正如其他答案中已经解释的那样,你可以使用反射绕过限制。

回答by Tapeshvar

Yes you could, as mentioned by @Jon Steet.

是的,你可以,正如@Jon Steet 所提到的。

Another way of accessing a private constructor is by creating a public static method within this class and have its return type as its object.

访问私有构造函数的另一种方法是在此类中创建一个公共静态方法,并将其返回类型作为其对象。

public class ClassToAccess
{

    public static void main(String[] args)
    {
        {
            ClassWithPrivateConstructor obj = ClassWithPrivateConstructor.getObj();
            obj.printsomething();
        }

    }

}

class ClassWithPrivateConstructor
{

    private ClassWithPrivateConstructor()
    {
    }

    public void printsomething()
    {
        System.out.println("HelloWorld");
    }

    public static ClassWithPrivateConstructor getObj()
    {
        return new ClassWithPrivateConstructor();
    }
}

回答by user3251696

you can access it outside of the class its very easy to access just take an example of singaltan class we all does the same thing make the private constructor and access the instance by static method here is the code associated to your query

您可以在类之外访问它,它很容易访问,仅以 singaltan 类为例,我们都做同样的事情使私有构造函数并通过静态方法访问实例这里是与您的查询相关联的代码

ClassWithPrivateConstructor.getObj().printsomething();

it will definately work because i have already tested

它肯定会工作,因为我已经测试过了

回答by kalyani chaudhari

Using java Reflection as follows :

使用java反射如下:

   import java.lang.reflect.Constructor;

   import java.lang.reflect.InvocationTargetException;

   class Test   
   {

      private Test()  //private constructor
      {
      } 
   }

  public class Sample{

      public static void main(String args[]) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException
     {

       Class c=Class.forName("Test"); //specify class name in quotes

       //----Accessing private constructor
       Constructor con=c.getDeclaredConstructor();
       con.setAccessible(true);     
       Object obj=con.newInstance();
   }   
}