我在下面有一个单例类继承的示例代码。但是,我没有预见到这段代码是否会发生任何隐藏的问题。有人可以分析并给我提示吗?
interface ChairIF {
public int getLeg();
public void test();
}
class ChairImpl implements ChairIF {
private static final Lock lock = new ReentrantLock();
private static ChairIF instance = null;
public static ChairIF getInstance(String clazzName) {
//get class by clazzName
Class clazz = null;
try {
clazz = Class.forName(clazzName);
} catch (ClassNotFoundException ex) {
lock.lock();
try {
if (instance == null) {
instance = new ChairImpl();
}
} finally {
lock.unlock();
}
}
//init singleton instance of clazzName
if (instance == null) {
lock.lock();
try {
if (instance == null) {
instance = (ChairIF) clazz.newInstance();
} else {
if (instance.getClass() != clazz) {
instance = (ChairIF) clazz.newInstance();
}
}
} catch (Exception ex) {
instance = new ChairImpl();
} finally {
lock.unlock();
}
} else {
lock.lock();
try {
if (!instance.getClass().getName().equals(clazz.getName())) {
instance = (ChairIF) clazz.newInstance();
}
} catch (Exception ex) {
instance = new ChairImpl();
} finally {
lock.unlock();
}
}
return instance;
}
public int getLeg() {
return 4;
}
public void test() {
throw new UnsupportedOperationException();
}
}
class ThreeLegChair extends ChairImpl {
public ThreeLegChair() {}
public int getLeg() {
return 3;
}
public void test() {
int i = 0;
while(i < 10000) {
System.out.println("i: " + i++);
}
}
}
class NoLegChair extends ChairImpl {
public NoLegChair() {}
public int getLeg() {
return 0;
}
public void test() {
int j = 0;
while(j < 5000) {
System.out.println("j: " + j++);
}
}
}
public class Test {
public static void main(String[] args) {
System.out.println(ChairImpl.getInstance("ThreeLegChair").getLeg());
System.out.println(ChairImpl.getInstance("NoLegChair").getLeg());
/***
TODO: build logic to run 2 test() simultaneously.
ChairImpl.getInstance("ThreeLegChair").test();
ChairImpl.getInstance("NoLegChair").test();
****/
}
}
如您所见,我确实在 2 个子类中放置了一些测试代码。 ThreeLegChair就是从0到10000循环打印出来。 NoLegChair 就是只从 0 到 5000 循环打印出来。
我在控制台日志中得到的结果是正确的。 ThreeLegChair 打印了 0 到 10000 的 i。NoLegChair 打印了 0 到 5000 的 j。
请分享你的想法:)
最佳答案
单例模式是使用私有(private)构造函数的概念实现的,即类本身负责创建类的单个实例(单例)并防止其他类创建对象。
现在由于构造函数是私有(private)的
,您不能首先继承单例类。 在您的情况下,我没有看到私有(private)构造函数,这使得它容易受到访问它的其他类创建对象的影响。
单例模式示例:
- 在 Java 中使用枚举
enum SingletonEnum { SINGLE_INSTANCE; public void doStuff() { System.out.println("Singleton using Enum"); } }
- 惰性初始化方法
class SingletonClass {
private static SingletonClass singleInstance; private SingletonClass() { // deny access to other classes } // The object creation will be delayed until getInstance method is called. public static SingletonClass getInstance() { if (null == singleInstance) { // Create only once singleInstance = new SingletonClass(); } return singleInstance; } }
但是,上面的示例可能无法保证多线程环境中的单例行为。推荐使用double checked locking确保您已创建此类的单个实例的机制。
关于java - 案例研究 : Singleton class inheritance - Good or bad?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21038149/