StackOverflowError,在我的代码中找不到我调用的地方

Dud*_*awg 2 java stack-overflow exception

我在Java中有一个StackOverflowError它并没有在我自己的代码中告诉我任何行,stacktrace的相关部分是:

java.lang.StringBuilder.append(StringBuilder.java:132)
java.util.AbstractMap.toString(AbstractMap.java:523)
java.lang.String.valueOf(String.java:2838)
java.lang.StringBuilder.append(StringBuilder.java:132)
java.util.AbstractCollection.toString(AbstractCollection.java:439)
java.lang.String.valueOf(String.java:2838)
Run Code Online (Sandbox Code Playgroud)

我已经尝试从throwable获取堆栈跟踪,但由于某种原因它不包含相关节点,我试图在我的代码中找到一些错误在哪里.此外,我已经尝试将堆栈大小减少到128k以更早地获得错误,但无济于事.

Paŭ*_*ann 6

对于a StackOverFlowError,堆栈跟踪经常被截断(因为它太长),这实际上没有帮助找到错误.

在您的情况下,假设您复制的部分是重复的部分,看起来您将地图添加到集合中,而集合又是原始地图的键或值,然后toString()在其中一个上使用这些对象.

然后toString(),map(在AbstractMap中)的默认实现StringBuilder.append(...)会调用其所有键和值,而这些键和值又会调用toString它们.对于AbstractCollection,同样适用于集合的元素.

(Jon的回答中的例子与两个集合有关,而不是地图和集合.)

解决方案:

  • 删除集合/地图中的循环.
  • 如果您的集合/地图图中需要循环:
    • 避免打电话toString()(和hashCode/ equals,也),或
    • 覆盖toString()其中一个方法来打破循环.


Jon*_*eet 5

这是一个会导致相同错误的示例,这可能会有所帮助:

import java.util.*;

public class Test
{
    public static void main(String[] args)
    {
        List<Object> list1 = new ArrayList<Object>();
        List<Object> list2 = new ArrayList<Object>();
        list1.add(list2);
        list2.add(list1);
        String text = list1.toString();
        System.out.println(text);
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,只需使用:

List<Object> list = new ArrayList<Object>();
list.add(list);
String text = list.toString();
Run Code Online (Sandbox Code Playgroud)

......也不会产生错误.它是足够聪明,如果集合是立即内本身-而不是嵌套在自身内部.

当然,你可能没有使用相同的集合,所以这可能会改变正在发生的事情 - 但希望这给了你一个起点.