Fix issue #761: ThreadSafeDoubleCheckLocking.java: Instantiating by Reflection call will be successful if you do that firstly (#920)

This commit is contained in:
Adrian Yao 2019-09-08 02:13:15 +08:00 committed by Ilkka Seppälä
parent 8c865e6b4d
commit f1410337b5
3 changed files with 25 additions and 1 deletions

View File

@ -38,5 +38,9 @@
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -35,12 +35,16 @@ public final class ThreadSafeDoubleCheckLocking {
private static volatile ThreadSafeDoubleCheckLocking instance;
private static boolean flag = true;
/**
* private constructor to prevent client from instantiating.
*/
private ThreadSafeDoubleCheckLocking() {
// to prevent instantiating by Reflection call
if (instance != null) {
if (flag) {
flag = false;
} else {
throw new IllegalStateException("Already initialized.");
}
}

View File

@ -22,6 +22,11 @@
*/
package com.iluwatar.singleton;
import org.junit.Test;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/**
* Date: 12/29/15 - 19:26 PM
*
@ -36,4 +41,15 @@ public class ThreadSafeDoubleCheckLockingTest extends SingletonTest<ThreadSafeDo
super(ThreadSafeDoubleCheckLocking::getInstance);
}
/**
* Test creating new instance by refection
*/
@Test(expected = InvocationTargetException.class)
public void testCreatingNewInstanceByRefection() throws Exception {
ThreadSafeDoubleCheckLocking instance1 = ThreadSafeDoubleCheckLocking.getInstance();
Constructor constructor = ThreadSafeDoubleCheckLocking.class.getDeclaredConstructor();
constructor.setAccessible(true);
ThreadSafeDoubleCheckLocking instance2 = (ThreadSafeDoubleCheckLocking) constructor.newInstance(null);
}
}