Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extending a singleton in Java

Tags:

java

singleton

What I'd like to do is just make a class that when you extend it, you automatically get the getInstance class. The problem is, when i extend it, I can't reference the child class. The only way I could see to do it is by typecasting ((ClassName)class.getInstance()) but its not very user-friendly. Any suggestions?

like image 273
Arhowk Avatar asked Apr 29 '13 02:04

Arhowk


2 Answers

You cannot extend a proper Singleton since it's supposed to have a private constructor:

Effective Java Item 2: Enforce the singleton property with a private constructor

like image 190
Evgeniy Dorofeev Avatar answered Nov 09 '22 05:11

Evgeniy Dorofeev


The only way to override a singleton is to have a singleton that expects to be overridden. The simplest way to do this is to provide Singleton that implements an interface (or is otherwise fully abstract itself) that internally instantiates an injected singleton upon the first use of getInstance().

public interface SingletonMethods // use a better name
{
    String getName();

    void doSomething(Object something);
}

public class Singleton // use a better name
{
    private Singleton() { /* hidden constructor */ }

    public static SingletonMethods getInstance()
    {
        return SingletonContainer.INSTANCE;
    }

    /**
     * Thread safe container for instantiating a singleton without locking.
     */
    private static class SingletonContainer
    {
        public static final SingletonMethods INSTANCE;

        static
        {
            SingletonMethods singleton = null;
            // SPI load the type
            Iterator<SingletonMethods> loader =
                ServiceLoader.load(SingletonMethods.class).iterator();

            // alternatively, you could add priority to the interface, or
            //  load a builder than instantiates the singleton based on
            //  priority (if it's a heavy object)
            // then, you could loop through a bunch of SPI provided types
            //  and find the "highest" priority one
            if (loader.hasNext())
            {
                singleton = loader.next();
            }
            else
            {
                // the standard singleton to use if not overridden
                singleton = new DefaultSingletonMethods();
            }

            // remember singleton
            INSTANCE = singleton;
        }
    }
}
like image 26
pickypg Avatar answered Nov 09 '22 06:11

pickypg