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
2025-03-18 08:42:14 +01:00
committed by GitHub
parent e403df81fc
commit 19d9d31bb7
6 changed files with 38 additions and 17 deletions
@@ -40,7 +40,10 @@ public final class BillPughImplementation {
* Private constructor to prevent instantiation from outside the class.
*/
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 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 IvoryTower() {
// to prevent instantiating by Reflection call
if (INSTANCE != null) {
throw new IllegalStateException("Already initialized.");
}
}
/**
@@ -24,6 +24,10 @@
*/
package com.iluwatar.singleton;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertThrows;
/**
* EnumIvoryTowerTest
*
@@ -37,4 +41,14 @@ class EnumIvoryTowerTest extends SingletonTest<EnumIvoryTower> {
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 org.junit.jupiter.api.Assertions.assertNotNull;
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 java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.concurrent.Callable;
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;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.lang.reflect.InvocationTargetException;
import org.junit.jupiter.api.Test;
/**
* ThreadSafeDoubleCheckLockingTest
*
@@ -42,15 +37,4 @@ class ThreadSafeDoubleCheckLockingTest extends SingletonTest<ThreadSafeDoubleChe
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));
}
}