什么是“私有构造函数捕获”习惯用法的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; } } 

存在私有构造函数以避免在将复制构造函数实现为此(px,py)时将发生的竞争条件。

这意味着,如果您没有私有构造函数,并且您以下列方式实现了复制构造函数:

 public SafePoint(SafePoint p) { this(px, py); } 

现在假设线程A正在访问SafePoint, p正在执行上面的复制构造函数的这个(px,py)指令,并且在不幸的时机,另一个也可以访问SafePoint的线程B执行对象的setter set(int x,int y) p 。 由于您的复制构造函数直接访问pxy实例变量而没有正确的锁定,因此可能会看到对象p的状态不一致。

私有构造函数通过同步的getter访问p的变量xy ,这样你就可以保证看到对象p的一致状态。