How do I instantiate a class with a private constructor?

Java Reflection gives to the programmer quite a bit of power and allows you to do all sorts of things you never thought possible. As Uncle Ben quoted in a famous movie, “With great power comes great responsibility”, Reflection allows us to circumvent a private constructor provided two things do not exist. (1) Provided that the code has not been obfuscated and (2) that a security manager with restricted policy is not in place.

Class with Private Constructor

Here is my rendition of the SecretAnnex…. At this point we have created a class SecretAnnex that can not be instantiated in the normal way. That is, using SecretAnnex secret = new SecretAnnex();. Right now the only alternative is to use reflection to instantiate the class.

public class SecretAnnex {

  private SecretAnnex() {
    System.out.println("Inside SecretAnnex constructor...");
  }
  
  public void tellMe() {
    System.out.println("If you want to keep a secret, you must also hide it from yourself.");
    System.out.println("    --George Orwell, 1984");
  }
}

Running the SecretStealer

The basic format of the our SecretStealer class is the following… We dynamically load the class we want, we then get a list of all the declared constructors available for the class, we will iterate through the entire list as we don’t know how many constructors there are, we will setting the accessibility flag to true on all constructors and then call the method tellMe()… Of course, if the code was obfuscated or had a different method signature things would be quite different.

Class<?> sa = Class.forName("com.avaldes.tutorials.SecretAnnex");
Constructor<?>[] constructors = sa.getDeclaredConstructors();

for (Constructor c : constructors) {
  c.setAccessible(true);
  SecretAnnex secret = (SecretAnnex) c.newInstance();
  secret.tellMe();
}

Full Program Listing

package com.avaldes.tutorials;

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

public class SecretStealer {

  public static void main(String[] args) throws 
    ClassNotFoundException, InstantiationException, IllegalAccessException, 
    IllegalArgumentException, InvocationTargetException {
    
    System.out.println("Running SecretStealer...");
    System.out.println("Dynamically loading the SecretAnnex class now..."); 
    Class<?> sa = Class.forName("com.avaldes.tutorials.SecretAnnex");
    
    // Get all the declared constructors
    System.out.println("Get all Declared Constructors...");
    Constructor<?>[] constructors = sa.getDeclaredConstructors();

    // Let's iterate through all and call the tellMe()
    System.out.println("Iterate through all constructors and call tellMe()...\n");
    for (Constructor c : constructors) {
      c.setAccessible(true);
      SecretAnnex secret = (SecretAnnex) c.newInstance();
      secret.tellMe();
    }
  }
}

Full Program Listing (SecretAnnex.java)

package com.avaldes.tutorials;

public class SecretAnnex {

  private SecretAnnex() {
    System.out.println("Inside SecretAnnex constructor...");
  }
  
  public void tellMe() {
    System.out.println("If you want to keep a secret, you must also hide it from yourself.");
    System.out.println("    --George Orwell, 1984");
  }
}

Output

Running SecretStealer...
Dynamically loading the SecretAnnex class now...
Get all Declared Constructors...
Iterate through all constructors and call tellMe()...

Inside SecretAnnex constructor...
If you want to keep a secret, you must also hide it from yourself.
    --George Orwell, 1984

Related Reflection Examples

  • Class Example
    Simple example shows you how to dynamically load and instantiate a class, get class name, package name, and superclass name.
  • Modifier Example
    Showing you how to get information about classes, fields and methods using modifier method.
  • Method Example
    Providing full details of how to get all methods, and invoke methods using reflection.

Please Share Us on Social Media

Facebooktwittergoogle_plusredditpinterestlinkedinmail

Leave a Reply

Your email address will not be published. Required fields are marked *