Skip to main content

Multiple Approach

(1) Native approach

class Settings {
private static Settings instance;

private Settings(){}
public static Settings getInstance() {
if (instance == null) this.instance = new Settings();
return instance;
}
}

This approach is simple but not thread-safe.

(2) Static Factory method approach

class Settings {
private Settings(){}

// Thread safe since this is static instance.
// Eager loading
private final static Settings INSTANCE = new Settings();

public static Settings getInstance() {
return INSTANCE;
}
}

This approach thread-safe but eager loading. \ This class always be created even though you don't use this class.

(3) BillPugh approach

class Settings {
private Settings(){}
// Thread safe
// Lazy loading
private static class SettingsHolder {
private final static Settings INSTANCE = new Settings();
}

public static Settings getInstance() {
return SettingsHolder.INSTANCE;
}
}

This approach is thread-safe and also be loaded lazily.

(4) Enum approach

enum Settings {
INSTANCE;
}

Enum is best simple approach. \ Enum is thread-safe but always be loaded eagerly. \ And does not support 'inheritance' from other class. \ Enum already inherits from Enum class in java.lang.Enum.java.

Summary

ApproachProsCons
NaiveSimpleNot thread-safe, Eager Loading
Static factory methodThread-safeEager Loading
BillPughRelative simple
Thread-safe
Lazy Loading
EnumBest simple
Thread-safe
Prevent reflection
Eager Loading
Unable to inheritance from other class

Use BillPugh approach when you have to lazy load or required to inheritance \ In all other situation, use Enum