gpt4 book ai didi

java - 集合的 toString() 方法中的 StackOverflowError 是一个错误吗?

转载 作者:行者123 更新时间:2023-12-02 02:22:10 24 4
gpt4 key购买 nike

我写了这段代码来演示:

List<Object> list1 = new ArrayList<>();
List<Object> list2 = new ArrayList<>();
list2.add(list1);
list1.add(list2);
list1.toString();

此代码将导致StackOverflowError

但是我知道java的集合中有一些努力来防止这种情况,例如这个代码可以正常工作:

List<Object> list1 = new ArrayList<>();
list1.add(list1);
list1.toString();

其他一些语言似乎也可以处理它(两种情况)。第一个例子没有“净化”而第二个例子是有原因的吗?这是一个错误吗?

最佳答案

这并不完全是一个错误 - 这更像是一种不幸的实用主义。 toString 应该尽最大努力不抛出任何东西(它是一个调试工具,这会很烦人 - 在 toString 计算期间没有真正需要报告无关情况) - 但它应该尝试的努力是有限的,因为 toString 也应该是高性能的,并且易于编写。

问题是,java是OO语言,东西都是封装的。仅通过查看组件是什么,无法知道在“组件”对象上调用 toString 是否最终会再次调用自己的 toString 。毕竟它只是一个对象(列表可以容纳任何东西 - 包括其他列表、集合、映射等)。与其他一些语言不同,Java 还具有完全可扩展的核心数据类型:您可以编写自己的列表实现,而且许多语言都这样做。 (例如,java.util.concurrent 有许多非常有用的核心集合 API 实现)。因此,试图通过集合之间的某种内部通信系统来迎合这种情况,会将管理所有这些的责任也放在扩展者身上,这不是务实的选择。

有一些非常棘手的方法,例如 try catch StackOverflow,或者在 ThreadLocal 中设置一个标志,如果该标志为 true,则返回一个备用值(因为这意味着在某个组件对象上调用 toString 最终会调用 toString又在你身上),但现在你必须指定 toString 计算不能将工作外包给其他线程。任何人都不太可能会这样做,但是在 toString 实现中添加一大堆奇怪的警告,或者将其放入一个小框架来传达递归组件的概念,这一切都完全不适合调试工具:使其紧密绑定(bind)且复杂。

关于java - 集合的 toString() 方法中的 StackOverflowError 是一个错误吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66233760/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com