AI Skill Report Card

Generated Skill

B-70·Feb 8, 2026·Source: Extension-page

Implementing Singleton Patterns in Java

Enum Singleton (Recommended):

Java
public enum ConfigSingleton { INSTANCE("default-config"); private String config; private ConfigSingleton(String config) { this.config = config; } public String getConfig() { return config; } public void setConfig(String config) { this.config = config; } } // Usage ConfigSingleton.INSTANCE.setConfig("production");
Recommendation
Consider adding more specific examples

Progress:

  • Identify singleton requirement (global state, expensive initialization)
  • Choose implementation approach (enum preferred)
  • Implement with thread safety considerations
  • Test for proper singleton behavior
  • Consider dependency injection alternatives

1. Enum Singleton Implementation

Java
public enum MySingleton { INSTANCE("initial-value"); private String data; private MySingleton(String data) { this.data = data; } public String getData() { return data; } public void setData(String data) { this.data = data; } }

2. Class-Based Singleton (Thread-Safe)

Java
public final class ClassSingleton { private static volatile ClassSingleton INSTANCE; private String data = "initial"; private ClassSingleton() {} public static ClassSingleton getInstance() { if (INSTANCE == null) { synchronized (ClassSingleton.class) { if (INSTANCE == null) { INSTANCE = new ClassSingleton(); } } } return INSTANCE; } public String getData() { return data; } public void setData(String data) { this.data = data; } }

3. Lazy Initialization Holder Pattern

Java
public final class LazyInitSingleton { private String data = "initial"; private LazyInitSingleton() {} private static class Holder { static final LazyInitSingleton INSTANCE = new LazyInitSingleton(); } public static LazyInitSingleton getInstance() { return Holder.INSTANCE; } }
Recommendation
Include edge cases

Example 1: Database Connection Pool

Java
public enum DatabasePool { INSTANCE; private final Connection connection; private DatabasePool() { // Expensive initialization this.connection = createConnection(); } public Connection getConnection() { return connection; } } // Usage Connection db = DatabasePool.INSTANCE.getConnection();

Example 2: Application Configuration

Java
public enum AppConfig { INSTANCE; private Properties props = new Properties(); private AppConfig() { loadConfiguration(); } public String getProperty(String key) { return props.getProperty(key); } } // Usage String dbUrl = AppConfig.INSTANCE.getProperty("database.url");

Example 3: Testing Singleton Behavior

Java
@Test public void testSingletonInstance() { MySingleton instance1 = MySingleton.INSTANCE; MySingleton instance2 = MySingleton.INSTANCE; assertSame(instance1, instance2); instance1.setData("modified"); assertEquals("modified", instance2.getData()); }
  1. Prefer Enum Singletons - Built-in serialization and thread safety
  2. Use volatile with double-checked locking - Prevents memory consistency errors
  3. Make constructor private - Prevents external instantiation
  4. Consider lazy initialization - Only create when needed
  5. Document thread safety - Be explicit about threading guarantees
  6. Implement proper equals/hashCode - Maintain object identity contracts
  1. Non-thread-safe implementation:
Java
// BAD - Race condition possible public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); // Multiple threads can reach here } return instance; }
  1. Reflection attacks on class-based singletons:
Java
// Problem: Reflection can break singleton Constructor<ClassSingleton> constructor = ClassSingleton.class.getDeclaredConstructor(); constructor.setAccessible(true); ClassSingleton newInstance = constructor.newInstance(); // Second instance!
  1. Serialization breaking singleton contract:
Java
// BAD - Deserialization creates new instance // Solution: Implement readResolve() private Object readResolve() { return getInstance(); }
  1. Using singleton as global variable:
Java
// BAD - Hard to test, tight coupling public void processData() { String config = ConfigSingleton.getInstance().getValue(); } // BETTER - Dependency injection public void processData(String config) { // Explicit dependency, easier to test }
  1. Multiple classloader issues:
  • Each classloader may create its own singleton instance
  • Consider using dependency injection frameworks for complex applications
  1. Garbage collection edge case:
  • Singleton can be GC'd if no references held
  • Rare but possible in long-running applications
0
Grade B-AI Skill Framework
Scorecard
Criteria Breakdown
Quick Start
11/15
Workflow
11/15
Examples
15/20
Completeness
15/20
Format
11/15
Conciseness
11/15