我正在阅读Java8集合界面文档.我注意到Java8 Collection Interface在描述中添加了这一段,它不包含在Java7 Collection Interface中.
执行集合的递归遍历的某些集合操作可能会失败,而自引用实例的例外情况是集合直接或间接包含自身.这包括clone(),equals(),hashCode()和toString()方法.实现可以可选地处理自引用场景,但是大多数当前实现不这样做.
关于为什么要包含这一段,我有点困惑.是因为Java7不能拥有直接或间接包含自身集合的自引用实例吗?然后Java8引入了新的界面或一些允许的新功能?
我正在寻找详细的解释,如果你举一个例子来说明你的观点,那将会很棒.谢谢!
在toString()用于格式List被指定; 它必须递归地toString()呈现内容并将它们呈现在由逗号分隔的列表中[ ... ].如果您创建List如下:
List<Object> list = new ArrayList<>();
list.add(list);
System.out.println(list);
Run Code Online (Sandbox Code Playgroud)
一个天真的实现toString()将抛出StackOverflowError(尝试它.)Collection在某些情况下,实现试图防止一些核心方法的这个问题; 这就是本段所说的.
是因为Java7不能拥有直接或间接包含自身集合的自引用实例吗?然后Java8引入了新的界面或一些允许的新功能?
我不这么认为.
在Java 8之前,实例当然可以自我引用.
在a中使用它们Collection可能会创建无限循环,并在运行时StackOverflowError抛出失败.
这里有两个类,其中实例字段之间具有循环依赖关系,并且toString()每个类的方法依赖于它们自己的字段.
指儿童的父母:
public class Parent {
private List<Child> childs;
public Parent(List<Child> childs) {
this.childs = childs;
}
@Override
public String toString() {
return "Parent [childs=" + childs + "]";
}
}
Run Code Online (Sandbox Code Playgroud)
父母的孩子:
public class Child {
private Parent parent;
public Parent getParent() {
return parent;
}
public void setParent(Parent parent) {
this.parent = parent;
}
@Override
public String toString() {
return "Child [parent=" + parent + "]";
}
}
Run Code Online (Sandbox Code Playgroud)
假设您现在创建了一个Child和一个关联的Parent:
List<Child> childs = new ArrayList<>();
Child child = new Child();
childs.add(child);
Parent parent = new Parent(childs);
child.setParent(parent);
Run Code Online (Sandbox Code Playgroud)
现在你可以调用:
parent.toString();
child.toString();
Run Code Online (Sandbox Code Playgroud)
或者在Collection例如:
childs.toString();
Run Code Online (Sandbox Code Playgroud)
您将得到完全相同的结果: java.lang.StackOverflowError
当子进程调用调用父进程的子进程的父进程时...
该文档很可能是用Java 8更新的,以强制执行这些方法的风险,因为Collection实现通常不解决它,并且有意义,因为必须避免隐藏错误的客户端代码的故障,否则问题永远不会被解决.
"实现可以选择性地处理自引用场景,但是大多数当前的实现都不会这样做."
| 归档时间: |
|
| 查看次数: |
452 次 |
| 最近记录: |