BAEL-4933 | Differences between static classes and the singleton pattern in Java (#11014)
* BAEL-4220 | A Guide to IllegalAccessError and when it happens * BAEL-4220 | A Guide to IllegalAccessError and when it happens | fix tests * BAEL-4220 | A Guide to IllegalAccessError and when it happens | fix tests * BAEL-4220 | A Guide to IllegalAccessError and when it happens | BDD test names * BAEL-4494 | .toArray(new MyClass[0]) or .toArray(new MyClass[myList.size()])? * BAEL-4494 | .toArray(new MyClass[0]) or .toArray(new MyClass[myList.size()])? * BAEL-4933 | Differences between static classes and the singleton pattern in Java Co-authored-by: root <anmoldeep0123@gmail.com>
This commit is contained in:
parent
1910561a54
commit
37db34cb8a
|
@ -0,0 +1,30 @@
|
|||
package com.baeldung.staticsingletondifference;
|
||||
|
||||
public class CachingSingleton implements SingletonInterface {
|
||||
|
||||
private CachingSingleton() {
|
||||
}
|
||||
|
||||
private static class SingletonHolder {
|
||||
public static final CachingSingleton instance = new CachingSingleton();
|
||||
}
|
||||
|
||||
public static CachingSingleton getInstance() {
|
||||
return SingletonHolder.instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String describeMe() {
|
||||
return "Caching Responsibilities";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String passOnLocks(MyLock lock) {
|
||||
return lock.takeLock(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void increment() {
|
||||
throw new UnsupportedOperationException("Not Supported Here");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.baeldung.staticsingletondifference;
|
||||
|
||||
public class FileSystemSingleton implements SingletonInterface{
|
||||
|
||||
private int filesWritten;
|
||||
|
||||
private FileSystemSingleton() {
|
||||
}
|
||||
|
||||
private static class SingletonHolder {
|
||||
public static final FileSystemSingleton instance = new FileSystemSingleton();
|
||||
}
|
||||
|
||||
public static FileSystemSingleton getInstance() {
|
||||
return SingletonHolder.instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String describeMe() {
|
||||
return "File System Responsibilities";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String passOnLocks(MyLock lock) {
|
||||
return lock.takeLock(2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void increment() {
|
||||
this.filesWritten++;
|
||||
}
|
||||
|
||||
public int getFilesWritten() {
|
||||
return filesWritten;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package com.baeldung.staticsingletondifference;
|
||||
|
||||
public class MyLock {
|
||||
|
||||
protected String takeLock(int locks) {
|
||||
return "Taken Specific Lock";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package com.baeldung.staticsingletondifference;
|
||||
|
||||
import java.io.ObjectStreamException;
|
||||
import java.io.Serializable;
|
||||
|
||||
public class SerializableCloneableSingleton implements SingletonInterface, Serializable, Cloneable {
|
||||
|
||||
private static final long serialVersionUID = -1917003064592196223L;
|
||||
|
||||
private int state;
|
||||
|
||||
private SerializableCloneableSingleton() {
|
||||
}
|
||||
|
||||
private static class SingletonHolder {
|
||||
public static final SerializableCloneableSingleton instance = new SerializableCloneableSingleton();
|
||||
}
|
||||
|
||||
public static SerializableCloneableSingleton getInstance() {
|
||||
return SingletonHolder.instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String describeMe() {
|
||||
throw new UnsupportedOperationException("Not Supported Here");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String passOnLocks(MyLock lock) {
|
||||
throw new UnsupportedOperationException("Not Supported Here");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void increment() {
|
||||
this.state++;
|
||||
}
|
||||
|
||||
public int getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
private Object readResolve() throws ObjectStreamException {
|
||||
return SingletonHolder.instance;
|
||||
}
|
||||
|
||||
public Object cloneObject() throws CloneNotSupportedException {
|
||||
return this.clone();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package com.baeldung.staticsingletondifference;
|
||||
|
||||
public interface SingletonInterface {
|
||||
|
||||
public String describeMe();
|
||||
|
||||
public String passOnLocks(MyLock lock);
|
||||
|
||||
public void increment();
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package com.baeldung.staticsingletondifference;
|
||||
|
||||
public class SingletonLock extends MyLock {
|
||||
|
||||
private SingletonLock() {
|
||||
}
|
||||
|
||||
private static class SingletonHolder {
|
||||
public static final SingletonLock instance = new SingletonLock();
|
||||
}
|
||||
|
||||
public static SingletonLock getInstance() {
|
||||
return SingletonHolder.instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String takeLock(int locks) {
|
||||
return "Taken Singleton Lock";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package com.baeldung.staticsingletondifference;
|
||||
|
||||
public class SubUtility extends SuperUtility {
|
||||
|
||||
public static String echoIt(String data) {
|
||||
return data;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package com.baeldung.staticsingletondifference;
|
||||
|
||||
public class SuperUtility {
|
||||
|
||||
public static String echoIt(String data) {
|
||||
return "SUPER";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
package com.baeldung.staticsingletondifference;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ForSingletonsUnitTest {
|
||||
|
||||
@Test
|
||||
public void whenStaticUtilClassInheritance_thenOverridingFails() {
|
||||
SuperUtility superUtility = new SubUtility();
|
||||
Assert.assertNotEquals("ECHO", superUtility.echoIt("ECHO"));
|
||||
Assert.assertEquals("SUPER", superUtility.echoIt("ECHO"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSingletonDerivesBaseClass_thenRuntimePolymorphism() {
|
||||
MyLock myLock = new MyLock();
|
||||
Assert.assertEquals("Taken Specific Lock", myLock.takeLock(10));
|
||||
myLock = SingletonLock.getInstance();
|
||||
Assert.assertEquals("Taken Singleton Lock", myLock.takeLock(10));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSingletonImplementsInterface_thenRuntimePolymorphism() {
|
||||
SingletonInterface singleton = FileSystemSingleton.getInstance();
|
||||
Assert.assertEquals("File System Responsibilities", singleton.describeMe());
|
||||
singleton = CachingSingleton.getInstance();
|
||||
Assert.assertEquals("Caching Responsibilities", singleton.describeMe());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSingleton_thenPassAsArguments() {
|
||||
SingletonInterface singleton = FileSystemSingleton.getInstance();
|
||||
Assert.assertEquals("Taken Singleton Lock", singleton.passOnLocks(SingletonLock.getInstance()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSingleton_thenAllowState() {
|
||||
SingletonInterface singleton = FileSystemSingleton.getInstance();
|
||||
IntStream.range(0, 5)
|
||||
.forEach(i -> singleton.increment());
|
||||
Assert.assertEquals(5, ((FileSystemSingleton) singleton).getFilesWritten());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSingleton_thenAllowSerializationDeserialization() {
|
||||
SingletonInterface singleton = SerializableCloneableSingleton.getInstance();
|
||||
singleton.increment();
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
try {
|
||||
new ObjectOutputStream(baos).writeObject(singleton);
|
||||
SerializableCloneableSingleton singletonNew = (SerializableCloneableSingleton) new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray())).readObject();
|
||||
Assert.assertEquals(1, singletonNew.getState());
|
||||
Assert.assertEquals(singleton.hashCode(), singletonNew.hashCode());
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSingleton_thenAllowCloneable() {
|
||||
SerializableCloneableSingleton singleton = SerializableCloneableSingleton.getInstance();
|
||||
singleton.increment();
|
||||
try {
|
||||
Assert.assertEquals(2, ((SerializableCloneableSingleton) singleton.cloneObject()).getState());
|
||||
} catch (CloneNotSupportedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue