这更像是一个样式问题,而不是"我有麻烦的问题"。对于零占位符对象(我是否使用正确的术语?),通常更喜欢使用单胎模式吗?为了易于讨论,这是一个例子:
public interface Foo {
void myMethod();
}
public class RealFoo implements Foo {
void myMethod() { /* Do something productive */ }
}
public class MyUniverse {
public static void main(String args[]) {
Foo[] fooArray = new Foo[10];
// do something productive that might result in Null objects in the array
for (Foo f : fooArray) {
f.myMethod(); // I DONT WANT TO DO if (f != null) blah blah
}
}
}
好吧,这是我的情况,是更喜欢做A还是B?
// A
public class NullFoo implements Foo {
public NullFoo() {}
public void myMethod() { /* don't need to do anything */ }
}
// B
public class NullFoo implements Foo {
private static NullFoo _instance = null;
protected NullFoo() {}
public static NullFoo getInstance() {
if (_instance == null) _instance = new NullFoo();
return _instance;
}
public void myMethod() { /* don't need to do anything */ }
}
谢谢!我的本能几乎总是优越,但也许我错过了一些东西,所以我问...
我会选择后者。我可能对此有些潮流,但我不认为单身人本质上是邪恶的。如果一堂课没有可变状态,那么单身人士就可以了。
不过,我将不受保护。另外,您的懒惰负担容易竞赛;我只会在声明行(private static final Foo instance = new NullFoo();
)上实例化nullfoo。最后,不要忘记让课程实际实现界面。:)
从虚拟机的角度来看,它会更好,因为java最多可以实例化一个对象。
好吧,很有趣。不能说我曾经面对过这个,但是...
我建议如果要始终如一地使用该实例(即它将始终做同样的事情),然后与B一起使用B。这样,您只有一个代表null对象的单个共享实例。这是一种节省空间的优化(而不是用NullFoos
混乱您的内存。与Collections#emptyList
几乎相同。
我必须说,就dsign而言,我看不出为什么您会//做一些有效的事情,这些效率可能会导致数组中的空对象将Foo
在您的fooArray
,然后用null替换。我确定您有自己的理由。
我将把单人用作枚举。
enum NullFoo implements Foo{
INSTANCE{
// implement methods here
}
}
请参阅:Singleton>枚举方式或阅读
项目3:用私人执行Singleton财产构造函数或枚举类型
在Joshua Bloch
我认为您不应该在此处使用接口。一个接口描述了一组实现其支持的类的操作。但是您正在使用nullfoo类来基本规定该要求。
那么,为什么不使用在其实现myMethod时无能为
public class BaseFoo
{
public void myMethod()
{
// do nothing
}
}
public class DerivedFoo extends BaseFoo
{
public void myMethod()
{
// do actual work
}
}
或,如果您的实际情况确实需要接口,请继续写if (foo != null) ...
测试。