84

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?

eebbesen
  • 5,070
  • 8
  • 48
  • 70
gmhk
  • 15,598
  • 27
  • 89
  • 112
  • 25
    With respect to Java, most similar interview questions can be answered "Yes, you can do virtually anything, but should you?! Generally, no!" Personally, i think it's a stupid question. I don't want my developers ever doing that so i don't care if they know about it. More practical language details should matter _far_ more. Knowing the more general utility of reflection is probably enough. Understanding OO design patterns and language gotchas is _far_ more important than obscure, should-be-avoided language constructs. – nicerobot Apr 08 '10 at 12:30
  • @nicerobot, I aggree with you, Some times this techniques defeat the actual meaning of the Purpose – gmhk Apr 08 '10 at 18:26
  • is it a good practice to allow accesing the private constructor using the reflection class? – gmhk Jun 18 '10 at 08:42
  • A class with only private constructors cannot be instantiated from the outside. This could be used for a class with only static support methods. (Sure you can use reflection, but for such class what would be the point.) – Daniel Sep 08 '15 at 13:49
  • I was asked about that today, but in C#, and as like you I answered "No", but one way to access a private constructor is using an `public static` method that returns the constructor and voilà! Now you have an instance of the private constructor stored in any variable (`var` in my case) without using reflection. – ArCiGo Nov 15 '17 at 22:23
  • read [ this](https://stackoverflow.com/questions/1196192/how-to-read-the-value-of-a-private-field-from-a-different-class-in-java) i think well help you – Fox Jan 07 '19 at 15:19
  • read [ this](https://stackoverflow.com/questions/1196192/how-to-read-the-value-of-a-private-field-from-a-different-class-in-java) i think well help you – Fox Jan 07 '19 at 15:23
  • @Daniel Singleton don't need static methods, except for one, getinstance. Then the static reference to the instance within the same class. Everything else don't need to be static. What you are describing is a utility. – Potato Jan 09 '19 at 13:36
  • @nicerobot although I agree with you about whether one should use reflection or not, I think you shouldn't say it's a stupid question. 1) you have no context 2) it makes sense to know that reflection exists and allows to do weird things. The question is not about whether it's a good thing or not. – coffee_machine Jun 05 '19 at 07:22
  • @coffee_machine 1) I do have the context. I’m responding to the post and its context. In that context, I do not like the question. 2) in a comment, I don’t “answer” the post, I comment on it. Had I wanted to answer it, I would have answered it with an explanation of why it was wrong. But thank you for caring about my 9yr old comment :-) – nicerobot Jun 05 '19 at 19:36

21 Answers21

110

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!";
    }
}
Lii
  • 11,553
  • 8
  • 64
  • 88
Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
76
  • 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?

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I used the second method you mentioned (without intention though :)) but seems it's not working in C#. Am I right? – Alireza Farahani Aug 14 '16 at 16:12
  • @alireza: Yes, C# has different rules. – Jon Skeet Aug 15 '16 at 03:59
  • `If it's a nested class, you can access it from the enclosing class` any example? – Yousha Aleayoub Sep 06 '16 at 09:54
  • 1
    @YoushaAleayoub: I'm sure it would take me about the same time to come up with an example as you: 1) Create a top-level class. 2) Create a nested class inside it, with a private constructor. 3) Call the private constructor from a method in the top-level class. Have you tried that yet? – Jon Skeet Sep 06 '16 at 10:19
  • 1
    Also, if it's an enclosing class you can access it from nested classes. – jdarthenay May 04 '18 at 13:44
24

This can be achieved using reflection.

Consider for a class Test, with a private constructor:

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]);
tonio
  • 10,355
  • 2
  • 46
  • 60
11

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 benefit This 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.

gprathour
  • 14,813
  • 5
  • 66
  • 90
  • Why would someone ask such a picky, language-specific question in an interview? – dfeuer Jun 25 '14 at 05:14
  • 1
    @dfeuer Well I think when you are going to the interview for Java Developer, then they might ask you language-specific (Java atleast*) questions. – gprathour Jun 25 '14 at 06:18
  • `Can you access a private constructor of a class and instantiate it?` Yes, using reflection. End of useless question that didn’t add any value. – Martin Marconcini Aug 09 '18 at 22:58
  • This answer is wrong. You can access a private constructor of a class via reflection and thus can instantiate it. However, if, inside the constructor, one were to ~~~throw new UnsupportedOperationException()~~~ one may override the reflection and make it near impossible, if not impossible, to instantiate for the exception is thrown, and although can be handled, cancels the instantiation. – JustAFellowCoder Apr 23 '19 at 20:10
  • Sorry, my comment was wrong. The original answer was actually motivated by a job interview. Sorry, I just read the headline... – mihca Oct 29 '21 at 07:40
5

I like the answers above, but there are two more nifty ways of creating a new instance of a class which has private constructor. It all depends on what you want to achieve and under what circumstances.

1: Using Java instrumentation and ASM

Well in this case you have to start the JVM with a transformer. To do this you have to implement a new Java agent and then make this transformer change the constructor for you.

First create the class transformer. This class has a method called transform. Override this method and inside this method you can use the ASM class reader and other classes to manipulate the visibility of your constructor. After the transformer is done, your client code will have access to the constructor.

You can read more about this here: Changing a private Java constructor with ASM

2: Rewrite the constructor code

Well, this is not really accessing the constructor, but still you can create an instance. Let's assume that you use a third-party library (let's say Guava) and you have access to the code but you don't want to change that code in the jar which is loaded by the JVM for some reason (I know, this is not very lifelike but let's suppose the code is in a shared container like Jetty and you can't change the shared code, but you have separate class loading context) then you can make a copy of the 3rd party code with the private constructor, change the private constructor to protected or public in your code and then put your class at the beginning of the classpath. From that point your client can use the modified constructor and create instances.

This latter change is called a link seam, which is a kind of seam where the enabling point is the classpath.

Community
  • 1
  • 1
Alma Alma
  • 1,641
  • 2
  • 16
  • 19
4

Using java Reflection as follows :

   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();
   }   
} 
kalyani chaudhari
  • 7,515
  • 3
  • 24
  • 21
3

Yes you could, as mentioned by @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();
    }
}
Tapeshvar
  • 338
  • 1
  • 13
  • I came across the same question and found various solutions as mentioned by @Jon Steet. Also came across new things like "Reflection" in java also by using factory methods. But Finally the simple implementation they were expecting was simple as this!!! Hope this helps guys:) – Tapeshvar Jun 25 '14 at 05:02
  • 1
    If this is an accepted answer, then the question is misleading. This doesn't access the constructor outside the class in which it is defined, it only accesses an object constructed by the private constructor. – Ray Jun 09 '16 at 13:13
2

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.

jarnbjo
  • 33,923
  • 7
  • 70
  • 94
2

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.

dkb
  • 4,389
  • 4
  • 36
  • 54
Sushan Baskota
  • 315
  • 3
  • 10
2

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

Niravdas
  • 371
  • 2
  • 19
1

Reflection is an API in java which we can use to invoke methods at runtime irrespective of access specifier used with them. To access a private constructor of a class:

My utility class

public final class Example{
    private Example(){
        throw new UnsupportedOperationException("It is a utility call");
    }
    public static int twice(int i)
    {
        int val = i*2;
        return val;
    }
}

My Test class which creates an object of the Utility class(Example)

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
class Test{
    public static void main(String[] args) throws Exception {
        int i =2;
        final Constructor<?>[] constructors = Example.class.getDeclaredConstructors();
        constructors[0].setAccessible(true);
        constructors[0].newInstance();
    }
}

When calling the constructor it will give the error java.lang.UnsupportedOperationException: It is a utility call

But remember using reflection api cause overhead issues

Animesh Jaiswal
  • 331
  • 3
  • 7
0

Look at Singleton pattern. It uses private constructor.

3biga
  • 392
  • 1
  • 5
  • 17
  • 1
    Singleton uses the private contructor, outside the class we wont be instantiated, but we use already instantiated class – gmhk Apr 08 '10 at 12:00
0

Yes you can instantiate an instance with a private constructor using Reflection, see the example I pasted below taken from java2s to understand how:

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

class Deny {
  private Deny() {
    System.out.format("Deny constructor%n");
  }
}

public class ConstructorTroubleAccess {
  public static void main(String... args) {
    try {
      Constructor c = Deny.class.getDeclaredConstructor();
      // c.setAccessible(true); // solution
      c.newInstance();

      // production code should handle these exceptions more gracefully
    } catch (InvocationTargetException x) {
      x.printStackTrace();
    } catch (NoSuchMethodException x) {
      x.printStackTrace();
    } catch (InstantiationException x) {
      x.printStackTrace();
    } catch (IllegalAccessException x) {
      x.printStackTrace();
    }
  }
}
madx
  • 6,723
  • 4
  • 55
  • 59
  • First setAccessible as true and then call newInstance(). c.setAccessible(true); c.newInstance(); – mahesh Oct 01 '16 at 12:26
0

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;
}
Nikhil Arora
  • 329
  • 3
  • 9
0

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.

0

I tried like this it is working. Give me some suggestion if i am wrong.

import java.lang.reflect.Constructor;

class TestCon {
private TestCon() {
    System.out.println("default constructor....");
}

public void testMethod() {
    System.out.println("method executed.");
  }
}

class TestPrivateConstructor {

public static void main(String[] args) {
    try {
        Class testConClass = TestCon.class;
        System.out.println(testConClass.getSimpleName());

        Constructor[] constructors =    testConClass.getDeclaredConstructors();
        constructors[0].setAccessible(true);
        TestCon testObj = (TestCon) constructors[0].newInstance();
        //we can call method also..
        testObj.testMethod();
    } catch (Exception e) {
        e.printStackTrace();
    }

}
}
0

Simple answer is yes we can have private constructors in Java.

There are various scenarios where we can use private constructors. The major ones are

  • Internal Constructor chaining
  • Singleton class design pattern
CodeRider
  • 564
  • 4
  • 15
0

We can create instance of private class by creating createInstance() in the same class and simply call the same method by using class name in main():

class SampleClass1{
        private SampleClass1() {
            System.out.println("sampleclass cons");
        }
        public static void createInstance() {
            SampleClass1 sc = new SampleClass1();
        }
    }

public class SingletonDemo {
    public static void main(String[] args) {
        //SampleClass1 sc1 = new SampleClass1();
        SampleClass1.createInstance();

     }
}
Procrastinator
  • 2,526
  • 30
  • 27
  • 36
ak_bhai
  • 41
  • 2
0

Also have another option create the getInstance() where we can create instance of private constructor inside same class and return that object.

class SampleClass1{
        private SampleClass1() {
            System.out.println("sample class constructor");
        }
        public static SampleClass1 getInstance() {
            SampleClass1 sc1 = new SampleClass1();
            return sc1;
        }
    }
    public class SingletonDemo {
    public static void main(String[] args) {
        SampleClass1 obj1 = SampleClass1.getInstance();
    }
  }
Procrastinator
  • 2,526
  • 30
  • 27
  • 36
ak_bhai
  • 41
  • 2
-1

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.

devoured elysium
  • 101,373
  • 131
  • 340
  • 557
-3

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

ClassWithPrivateConstructor.getObj().printsomething();

it will definately work because i have already tested