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> <artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

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

View File

@ -22,6 +22,11 @@
*/ */
package com.iluwatar.singleton; 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 * Date: 12/29/15 - 19:26 PM
* *
@ -36,4 +41,15 @@ public class ThreadSafeDoubleCheckLockingTest extends SingletonTest<ThreadSafeDo
super(ThreadSafeDoubleCheckLocking::getInstance); 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);
}
} }