我有一个看起来像这样的课程:
public class Node {
private final Node otherNode;
public Node(Node otherNode) {
this.otherNode = otherNode;
}
}
并希望做类似
的事情Node n1, n2 ;
n1 = new Node(n2);
n2 = new Node(n1);
但显然不能,因为n2尚未初始化。我不想使用setter来设置otherNode,因为它是最终的,因此只能设置一次。实现这一目标的最简洁方法是什么?是否有一些我不熟悉的Java语法让我这样做?我应该使用除了构造函数之外的初始化方法(丑陋),还是只使用一个setter(也很难看)?
答案 0 :(得分:9)
让第二个构造函数不带参数并构造自己的Node
,将自己作为另一个的“其他”传递。
public class Node
{
private final Node otherNode;
public Node(Node other)
{
otherNode = other;
}
public Node()
{
otherNode = new Node(this);
}
public Node getOther()
{
return otherNode;
}
}
然后使用它时:
Node n1 = new Node();
Node n2 = n1.getOther();
确保他们互相引用:
System.out.println(n1 == n1.getOther().getOther());
System.out.println(n2 == n2.getOther().getOther());
System.out.println(n1 == n2.getOther());
System.out.println(n2 == n1.getOther());
这些都打印true
。
答案 1 :(得分:2)
(这是rgettman答案的补充。)
更通用的解决方案是编写如下构造函数:
private Node(final int numNodesInLoop) {
if(numNodesInLoop < 1) {
throw new IllegalArgumentException();
}
Node head = this;
for(int i = 1; i < numNodesInLoop) {
head = new Node(head);
}
this.otherNode = head;
}
具有两个节点的情况将被实例化为new Node(2)
。
根据user949300对rgettman的回答,我做了上面的private
,因为Node
构造函数的含义是int
不太可猜测(它会创建一个循环) ?!),所以最好将它包装在名称使其功能清晰的static
工厂方法中:
public static Node newNodeLoop(final int numNodes) {
return new Node(numNodes);
}
(如果你以后需要另外一个构造函数需要int
,无论出于什么原因,这也更具有前瞻性。你可以修改这个构造函数来获取一个伪参数,只是足以告诉编译器你想要什么构造函数。工厂方法仍然具有相同的契约。)