我当时正在为个人备忘单收集设计模式,至少在我看来,在Head First Design Patterns(由Eric Freeman,Elisabeth Robson,Bert Bates,Kathy Sierra)中发现了一段奇怪的代码.
我认为我不允许在此处发布代码的确切部分,但我将重现令我震惊的代码:
假设我们之前已经使用公共方法runSomeCode()定义了类A,那么我们的类B如下:
public class B {
A a;
A b;
A x = a;
public B() {
a = new A();
b = new A();
}
public void testB()
{
x.runSomeCode();
}
}
我对这段代码的第一印象是对B实例testB方法的任何调用都应该抛出NullPointerException,但是我无法想象他们会发布这样的错误.
如果这本书是对的,我理解
x = a;
必须在B构造函数执行结束时完成,但是我仍然对这种感觉感到惊讶,我的问题是:
>我错了吗?
> Java总是这样吗?
>在那种情况下(我个人认为这有点令人困惑):在将来的Java版本中可能会删除它吗?
>您会尝试避免吗?
这是本书的示例:
我担心的情况是numberGumballs = 0时;
编辑二
我想我知道该示例发生了什么.
在书中,引用的类不是声明为静态的,但是几分钟前,我认为如果A是静态的,则可以编译.因此,也许,书的作者从一个使用静态类的较大项目中获得了代码.所以我尝试了一下,这次,它确实起作用了,但是该示例似乎仍然是错误的,并且以下代码对State pattern毫无意义.
public class B {
public static class Base {
public static void runSomeCode() { System.out.println("Base!"); }
}
public static class A extends Base {
public static void runSomeCode() { System.out.println("A!"); }
};
A a;
A b;
A x = a;
public B() {
a = new A();
b = new A();
}
public void testB()
{
x.runSomeCode();
}
}
另一个编辑
在本书示例中,我似乎并不是第一个注意到此问题的人,
在O’Reilly site errata section, under unconfirmed erratas sub-section,您可以找到:
最佳答案
要回答您的问题:
>相信您错了,根据Java 8 Specification字段初始化程序是在构造函数体之前执行的.
>我相信它已经存在,但是并不想遍历每个版本的规范.我不知道有什么变化.
>我对此表示怀疑,因为它是规范的一部分,如果他们对其进行更改,将会破坏兼容性.但
>在这种情况下,可以通过将x的赋值移动到构造函数中来轻松地将代码更改为明确说明初始化的顺序.将其作为字段初始值设定项对我来说没有任何好处.
这个“模式”的重点是什么?您仅得到两个本来可以做的引用…为什么不只使用a呢?