feat: Fix Singleton typo and extend reflection handling to remaining implementations (#3203)

* fix typo

* adding Reflection handling to other Singleton implementations
This commit is contained in:
smile-ab authored and GitHub committed 2025-03-18 09:42:14 +02:00
1 parent e403df81fc
commit 19d9d31bb7
6 files changed
+38 -17

No files matched your search

@@ -40,7 +40,10 @@ public final class BillPughImplementation {
* Private constructor to prevent instantiation from outside the class. * Private constructor to prevent instantiation from outside the class.
*/ */
private BillPughImplementation() { private BillPughImplementation() {
// private constructor // to prevent instantiating by Reflection call
if (InstanceHolder.instance != null) {
throw new IllegalStateException("Already initialized.");
}
} }
/** /**
@@ -43,6 +43,10 @@ public final class InitializingOnDemandHolderIdiom {
* Private constructor. * Private constructor.
*/ */
private InitializingOnDemandHolderIdiom() { private InitializingOnDemandHolderIdiom() {
// to prevent instantiating by Reflection call
if (HelperHolder.INSTANCE != null) {
throw new IllegalStateException("Already initialized.");
}
} }
/** /**
@@ -33,6 +33,10 @@ public final class IvoryTower {
* Private constructor so nobody can instantiate the class. * Private constructor so nobody can instantiate the class.
*/ */
private IvoryTower() { private IvoryTower() {
// to prevent instantiating by Reflection call
if (INSTANCE != null) {
throw new IllegalStateException("Already initialized.");
}
} }
/** /**
@@ -24,6 +24,10 @@
*/ */
package com.iluwatar.singleton; package com.iluwatar.singleton;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertThrows;
/** /**
* EnumIvoryTowerTest * EnumIvoryTowerTest
* *
@@ -37,4 +41,14 @@ class EnumIvoryTowerTest extends SingletonTest<EnumIvoryTower> {
super(() -> EnumIvoryTower.INSTANCE); super(() -> EnumIvoryTower.INSTANCE);
} }
/**
* Test creating new instance by reflection.
*/
@Override
@Test
void testCreatingNewInstanceByReflection() throws Exception {
// Java does not allow Enum instantiation http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.9
assertThrows(ReflectiveOperationException.class, EnumIvoryTower.class::getDeclaredConstructor);
}
} }
@@ -27,8 +27,10 @@ package com.iluwatar.singleton;
import static java.time.Duration.ofMillis; import static java.time.Duration.ofMillis;
import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTimeout; import static org.junit.jupiter.api.Assertions.assertTimeout;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
@@ -106,4 +108,14 @@ abstract class SingletonTest<S> {
} }
/**
* Test creating new instance by reflection.
*/
@Test
void testCreatingNewInstanceByReflection() throws Exception {
var firstTimeInstantiated = this.singletonInstanceMethod.get();
var constructor = firstTimeInstantiated.getClass().getDeclaredConstructor();
constructor.setAccessible(true);
assertThrows(InvocationTargetException.class, () -> constructor.newInstance((Object[]) null));
}
} }
@@ -24,11 +24,6 @@
*/ */
package com.iluwatar.singleton; package com.iluwatar.singleton;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.lang.reflect.InvocationTargetException;
import org.junit.jupiter.api.Test;
/** /**
* ThreadSafeDoubleCheckLockingTest * ThreadSafeDoubleCheckLockingTest
* *
@@ -42,15 +37,4 @@ class ThreadSafeDoubleCheckLockingTest extends SingletonTest<ThreadSafeDoubleChe
super(ThreadSafeDoubleCheckLocking::getInstance); super(ThreadSafeDoubleCheckLocking::getInstance);
} }
/**
* Test creating new instance by refection.
*/
@Test
void testCreatingNewInstanceByRefection() throws Exception {
ThreadSafeDoubleCheckLocking.getInstance();
var constructor = ThreadSafeDoubleCheckLocking.class.getDeclaredConstructor();
constructor.setAccessible(true);
assertThrows(InvocationTargetException.class, () -> constructor.newInstance((Object[]) null));
}
} }