Reflection Safe Private Constructor Singleton Object

Private constructor cannot be called outside the class, using private constructor, we can make sure that the Singleton object will be created using getAppleInstance method only.
Private objects, variables, methods and constructors can be modified to behave as public using Reflection and multiple Singleton objects can be created as shown below.

package org.wesome.dsalgo.design.pattern.singleton;

public class Apple {
    static Apple appleInstance;

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

     public static Apple getAppleInstance() {
        System.out.println("Apple getAppleInstance");
        if (Objects.isNull(appleInstance)) {
            appleInstance = new Apple();
        }
        return appleInstance;
    }
}
package org.wesome.dsalgo.design.pattern.singleton;

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

public class SingletonClass {
    public static void main(String[] args) {
        System.out.println(Apple.getAppleInstance());
        Apple apple = null;
        /*  using reflection, private constructor can be used to create instance of Apple class    */
        try {
            Class<Apple> clazz = Apple.class;
            Constructor<Apple> cons = clazz.getDeclaredConstructor();
            cons.setAccessible(true);
            apple = cons.newInstance();

        } catch (InvocationTargetException | NoSuchMethodException | InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
        System.out.println("apple = " + apple);
    }
}
plugins {
    id 'java'
    id "io.freefair.lombok" version "6.4.1"
}

group = 'org.wesome'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = JavaVersion.VERSION_1_8

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter:5.6.2'
}

test {
    useJUnitPlatform()
}

 

a private constructor cannot be saved from being modified as public and used to create Singleton instances, but it can throw exceptions while doing and will prohibit the multiple object creation.

package org.wesome.dsalgo.design.pattern.singleton;

import java.util.Objects;

public class Apple {
    static Apple appleInstance;

    private Apple() {
        System.out.println("Apple private default constructor");
        if (Objects.nonNull(Apple.appleInstance)) {
            throw new InstantiationError("Creating of this object is not allowed.");
        }

    }

    public static Apple getAppleInstance() {
        System.out.println("Apple getAppleInstance");
        if (Objects.isNull(appleInstance)) {
            appleInstance = new Apple();
        }
        return appleInstance;
    }
}
package org.wesome.dsalgo.design.pattern.singleton;

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

public class SingletonClass {
    public static void main(String[] args) {
        System.out.println(Apple.getAppleInstance());
        Apple apple = null;
        try {
            Class<Apple> clazz = Apple.class;
            Constructor<Apple> cons = clazz.getDeclaredConstructor();
            cons.setAccessible(true);
            apple = cons.newInstance();

        } catch (InvocationTargetException | NoSuchMethodException | InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
        System.out.println("apple = " + apple);
    }
}
plugins {
    id 'java'
    id "io.freefair.lombok" version "6.4.1"
}

group = 'org.wesome'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = JavaVersion.VERSION_1_8

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter:5.6.2'
}

test {
    useJUnitPlatform()
}

 

follow us on