[Java] [Read Effective Java] Chapter 2, Item 3 Force singleton property with private constructor or enum type

3 minute read

Enforce singleton properties with #private constructor or enum type

Before Java1.5, there were two ways to implement a singleton (Example 1, Example 2), but the third method (Example 4) that was made possible with 1.5 is the best story.

Glossary

Singleton

A type of design pattern. Sometimes called “Singleton pattern”. In short, a class that is instantiated exactly once. It is used when you want to realize the state that there is always only one instance of a certain class.

How to make a singleton

  • Declare the constructor as private. (To prevent the side that uses this class from calling the constructor)

  • The method getInstance() that acquires an instance is declared static. With this, the user can get the instance by calling Singleton#getInstance( ).

Singleton sample


/**
 * Application-wide setting information
 */
public class Config {
    /**
     * Declare the constructor as private so that it cannot be instantiated from the outside
     */
    private Config() {
        // Actually setting information from file database etc.
        // write the read process here
    }

    /**
     * Returns the only instance
     * @return the only instance of this class
     */
    public static Config getInstance() {
        return ConfigInstanceHolder.INSTANCE;
    }

    /**
     * Returns the setting value corresponding to the specified key
     * @param key Setting key
     * @return setting value
     */
    public String getValue(String key) {
        // Actually the setting information read by the constructor
        // Write the process to return here
        return ....;
    }

    /**
     * An inner class that holds the only instance of the Config class
     */
    public static class ConfigInstanceHolder {
        /** only instance */
        private static final Config INSTANCE = new Config();
    }
}

enum type

Enum (enum type) is a type that can store multiple constants in one. The constants defined by Enum are called enumerators.

public class Main {
 
    public static void main(String[] args) {
        Fruit fruit_type = Fruit.Orange;
        
        System.out.println(fruit_type);
    }
    
    protected enum Fruit {
        Orange,
        Apple,
        Melon
    };
    
}

Execution result


Orange

Elvis Presley

Great rock and roller I like “A Little Less Conversation” https://www.youtube.com/watch?v=Zx1_6F-nCaw

Elvis has left the Building.

It is an expression related to a famous episode of popular singer Elvis Presley of the past. Even though Presley’s concert was over, the announcement was sent to the audience who was not expecting to return home expecting Angkor, “Elvis has left this building”, urging the audience to leave the venue. ..

It is now used for any event that has ended.

Sample code

1 How to make a singleton before 1.5

We make the constructor priavte and provide public static members so that the user of the class can access the only instance of the class.

The private constructor is called once to initialize the public static final field Elvis.INSTANCE. This guarantees that Elvis is the only one in the world.

Example 1



// Singleton with public final field
public class Elvis{
    public static final Elvis INSTANCE = new Elvis();
    private Elvis() {...}

    public void leaveTheBuliding() {...}

}

How to make a singleton before ###1.5 Part 2 The second method is to make the first member public static. Return the object reference with Elvis.getInstance(). The nice thing about this is that the declaration makes it obvious that the class is a singleton.

Example 2



//Singleton with static factory method
public class Elvis{
    private static final Elvis INSTANCE = new Elvis();
    private Elvis() {...}
    public static Elvis getInstance() {return INSTANCE;}

    public void leaveTheBuilding() {...}
}

However, there is a possibility that there is a fake in Elvis created by the method of Example 1 and Example 2, and it is necessary to add the following method to prevent it.

Example 3



// readResolve method to retain singleton properties
private Object readResolve() throws ObjectStreamException{
    /*
     * Return the real Elvis and turn the Elvis fake into a garbage collector
     * Clean up.
     *
     */
    return INSTANCE;
}

Latest best way

The third way that you can do with Java 1.5. Simply create an enum type with a single element. It’s a simple statement and there is an iron wall that does not allow fake, so if you make a singleton, use this method.

Example 4



// enum singleton-preferred method
public enum Elvis {
    INSTANCE;

    public void leaveTheBuilding() {...}
}

Continue

[Read Effective Java] Chapter 2, Item 4 “Force uninstantiable with private constructor” https://qiita.com/Natsukii/items/661b645482d814b73914