How can I access a private constructor of a class?

2019-01-16 15:20发布

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

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?

18条回答
我欲成王,谁敢阻挡
2楼-- · 2019-01-16 16:19

The basic premise for having a private constructor is that having a private constructor restricts the access of code other than own class' code from making objects of that class.

Yes we can have private constructors in a class and yes they can be made accessible by making some static methods which in turn create the new object for the class.

 Class A{
private A(){
}
private static createObj(){
return new A();
}

Class B{
public static void main(String[]args){
A a=A.createObj();
}}

So to make an object of this class, the other class has to use the static methods.

What is the point of having a static method when we are making the constructor private?

Static methods are there so that in case there is a need to make the instance of that class then there can be some predefined checks that can be applied in the static methods before creation of the instance. For example in a Singleton class, the static method checks if the instance has already been created or not. If the instance is already created then it just simply returns that instance rather than creating a new one.

 public static MySingleTon getInstance(){
    if(myObj == null){
        myObj = new MySingleTon();
    }
    return myObj;
}
查看更多
一夜七次
3楼-- · 2019-01-16 16:20

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. Also, spring framework containers can access the private constructor of beans and this framework has used java reflection API. The following code demonstrate the way of accessing the private constructor.

class Demo{
     private Demo(){
      System.out.println("private constructor invocation");
     }
}

class Main{
   public static void main(String[] args){
       try{
           Class class = Class.forName("Demo");
           Constructor<?> con = string.getDeclaredConstructor();
           con.setAccessible(true);
           con.newInstance(null);
       }catch(Exception e){}

   }
}

output:
private constructor invocation

I hope you got it.

查看更多
够拽才男人
4楼-- · 2019-01-16 16:20

Look at Singleton pattern. It uses private constructor.

查看更多
再贱就再见
5楼-- · 2019-01-16 16:22

We can not access private constructor outside the class but using Java Reflection API we can access private constructor. Please find below code:

public class Test{
    private Test()
    System.out.println("Private Constructor called");
}
}


public class PrivateConsTest{
    public void accessPrivateCons(Test test){

        Field[] fields = test.getClass().getDeclaredFields();

        for (Field field : fields) {
            if (Modifier.isPrivate(field.getModifiers())) {
                field.setAccessible(true);
                System.out.println(field.getName()+" : "+field.get(test));
            }
        }
    }
}

If you are using Spring IoC, Spring container also creates and injects object of the class having private constructor.

查看更多
三岁会撩人
6楼-- · 2019-01-16 16:24

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!";
    }
}
查看更多
成全新的幸福
7楼-- · 2019-01-16 16:26

I hope This Example may help you :

package MyPackage;

import java.lang.reflect.Constructor;

/**
 * @author Niravdas
 */

class ClassWithPrivateConstructor {

    private ClassWithPrivateConstructor() {
        System.out.println("private Constructor Called");
    }

}
public class InvokePrivateConstructor 
{
     public static void main(String[] args) {
        try
        {
           Class ref = Class.forName("MyPackage.ClassWithPrivateConstructor");
           Constructor<?> con = ref.getDeclaredConstructor();
           con.setAccessible(true);
           ClassWithPrivateConstructor obj = (ClassWithPrivateConstructor) con.newInstance(null);
       }catch(Exception e){
           e.printStackTrace();
       }
    }

}

Output: private Constructor Called

查看更多
登录 后发表回答