【发布时间】:2012-07-06 10:39:47
【问题描述】:
有人可以通过示例向我解释私有构造函数捕获习语,并指出我们真正需要/不需要这种设计的地方吗?
【问题讨论】:
标签: java
有人可以通过示例向我解释私有构造函数捕获习语,并指出我们真正需要/不需要这种设计的地方吗?
【问题讨论】:
标签: java
目的是在施工期间获取临时价值。
Java Puzzlers的解决方案53中给出了一个例子:
public class MyThing extends Thing {
private final int arg;
public MyThing() {
this(SomeOtherClass.func());
}
private MyThing(int i) {
super(i);
arg = i;
}
}
在这种情况下,我们想要捕获并存储我们希望传递给超类构造函数的参数。为此,我们创建了一个私有辅助构造函数,然后我们的公共构造函数调用它。
【讨论】:
在Java Concurrency In Practice第4章4.3.5节中给出了一个例子的解释。
public class SafePoint {
private int x, y;
private SafePoint(int[] a) {
this(a[0], a[1]);
}
public SafePoint(SafePoint p) {
this(p.get());
}
public SafePoint(int x, int y) {
this.x = x;
this.y = y;
}
public synchronized int[] get() {
return new int[] { x, y };
}
public synchronized void set(int x, int y) {
this.x = x;
this.y = y;
}
}
私有构造函数的存在是为了避免复制构造函数被实现为 this(p.x, p.y) 时会发生的竞争条件。
这是什么意思,如果你没有私有构造函数并且你通过以下方式实现复制构造函数:
public SafePoint(SafePoint p) {
this(p.x, p.y);
}
现在假设线程 A 可以访问 SafePoint p 在复制构造函数的 this(p.x, p.y) 指令之上执行,并且在不幸的时间另一个线程 B 也可以访问 SafePoint p 在对象 p 上执行 setter set(int x, int y)。由于您的复制构造函数在没有适当锁定的情况下直接访问 p 的 x 和 y 实例变量,因此可能会看到对象 p 的不一致状态。
当私有构造函数通过同步的 getter 访问 p 的变量 x 和 y 时,可以保证看到一致对象的状态 p。
【讨论】: