3

我有一个看起来像这样的类:

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 语法让我这样做?除了构造函数(丑陋)之外,我应该使用初始化方法,还是只使用一个设置器(也丑陋)?

4

2 回答 2

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

于 2013-05-23T23:58:07.080 回答
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).

private根据 user949300 对 rgettman 的回答的评论,我做了上述操作,因为Node采用 an 的构造函数的含义int不是很容易猜测(它创建了一个循环?!),所以最好将它包装在一个static工厂方法中,它的名字使它功能明确:

public static Node newNodeLoop(final int numNodes) {
    return new Node(numNodes);
}

(这也更具前瞻性,以防您以后需要另一个构造函数,int无论出于何种原因。然后您可以修改此构造函数以获取一个虚拟参数,足以告诉编译器您使用什么构造函数想要。工厂方法仍然具有相同的合同。)

于 2013-05-24T15:57:58.240 回答