Java 为什么在向双链接列表添加第二个元素时会发生堆栈溢出?

Java 为什么在向双链接列表添加第二个元素时会发生堆栈溢出?,java,Java,我创建了一个双链接列表,它可以无错误地运行。但是当我使用debug检查此程序时,在添加第二个元素时会出现java.lang.StackOverflowerError。如果我不重写toString(),程序将正常。但是我想知道为什么不重写toString()? 包com.study.testcollection.com.study.testlinkedlist public class Node { private Node per; private Object obj;

我创建了一个双链接列表,它可以无错误地运行。但是当我使用debug检查此程序时,在添加第二个元素时会出现java.lang.StackOverflowerError。如果我不重写toString(),程序将正常。但是我想知道为什么不重写toString()? 包com.study.testcollection.com.study.testlinkedlist

public class Node {
    private Node per;
    private Object obj;
    private Node next;
    public Node getPer() {
        return per;
    }
    public Object getObj() {
        return obj;
    }
    public Node getNext() {
        return next;
    }
    public void setPer(Node per) {
        this.per = per;
    }
    public void setObj(Object obj) {
        this.obj = obj;
    }
    public void setNext(Node next) {
        this.next = next;
    }
    @Override
   //if don't write this function,the program will be normal.Why?
    public String toString() {
        return "Node{" +
                "per=" + per +
                ", obj=" + obj +
                ", next=" + next +
                '}';
    }
}
package com.study.testcollection.com.study.testlinkedlist;
public class Mylinkedlist {
    Node first = null;
    Node last = null;
    public void add(Object e){
        if (first == null){
            Node n = new Node();
            n.setObj(e);
            n.setPer(null);
            n.setNext(null);
            first = n;
            last = n;
        }
        else{
            Node n = new Node();
            n.setObj(e);
            last.setNext(n);
            n.setPer(last);
            n.setNext(null);
            last = n;
        }
    }
    public static void main(String[] args) {
        Mylinkedlist a = new Mylinkedlist();
        a.add("hello");
        a.add("Bob");//occur error when it is executed
    }
}

这就是它的样子。当您这样做时:

System.out.println(a.first.toString());
toString
定义为:

public String toString() {
    return "Node{" +
            "per=" + per +
            ", obj=" + obj +
            ", next=" + next +
            '}';
}
  • 您尝试打印下一个
    n
  • n
    尝试按打印上一个
    per
  • 上一次
    per
    再次尝试打印
    next
  • next
    调用previous
    per
    等等
导致stackoverflow,因为调用永远不会结束。如上图所示,在前进箭头和上一个箭头中反复迭代

要修复它,您可以从
节点
中删除
toString
,并替换为:

public String forward() {
    return "Node{" +
            ", obj=" + obj +
            ", next=" + next +
            '}';
}

public String backward() {
    return "Node{" +
            ", obj=" + obj +
            ", prev=" + per +
            '}';
}
您的“next”字段指向一个节点,因此Node.toString()被无限调用,从而导致stackoverflow。 如果需要使用toString()方法,可以按如下方式修改:

public String toString() {
        String n = next != null ? next.obj.toString():"null";
        String p = per != null ? per.obj.toString():"null";
        return "Node{" +
                "per=" + p +
                ", obj=" + obj +
                ", next=" + n +
                '}';
    }

你能发布完整的代码吗?谢谢你的评论,我已经修改了这个问题