我在接受采访时被问到这个问题.我有一个基类(类说A),然后两个子类B和C.现在,我有超过B和C的构造函数没有控制(那些构造函数不能是私有的,必须是公开的),但要求是每一个实例B,并C应该是一个单身.我怎样才能做到这一点?
我想我会在构造函数中执行此操作A.让它来调用this.getClass(),并使用它在私有HashSet中进行查找.如果你得到一个命中,那么之前已经创建了一个类的实例,并且你抛出一个异常.
public abstract class A {
private static HashSet<Class<?>> classes = new HashSet<Class<?>>();
public A () {
synchronized (classes) {
Class<?> c = this.getClass();
if (classes.contains(c)) {
throw NotSingletonException("Class " + c + " is not singleton");
}
classes.add(c);
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果你安排所有A的构造函数都这样做,那么子类就无法避免检查.并且由于JLS不允许你在一个this()或super()调用周围放置一个try/catch ,一旦抛出异常,子类的构造函数就不能正常返回.
我会说这是一个非常难的面试问题......
@emory评论:
如果B和C不是最终的怎么办?然后我可以创建类B1,B2,C1,C2等.
这里的问题(如果它算作一个问题)是B1和B2实例也是B实例,这意味着B实例不再是单例...取决于你想要实现的单例的定义.
我可以看到几种处理方式:
您可以反思地测试子类修饰符,看看类是否为final,并拒绝创建非final类的实例...以防万一.
你可以HashSet<Class>用a 代替List<Class>.然后每次A调用构造函数时,它都会遍历调用elem.isAssignableFrom(c)每个元素类的列表.如果任何调用返回true,则违反(strict)单例不变量,因此应抛出异常.
可能需要根据您试图强制执行的单例模型来调整逻辑,但通用解决方案适用:记录类并检查/比较新类与以前的类.
| 归档时间: |
|
| 查看次数: |
381 次 |
| 最近记录: |