Java 8与Java7集合接口:自引用实例

OLI*_*KOO 6 java-7 java-8

我正在阅读Java8集合界面文档.我注意到Java8 Collection Interface在描述中添加了这一段,它不包含在Java7 Collection Interface中.

执行集合的递归遍历的某些集合操作可能会失败,而自引用实例的例外情况是集合直接或间接包含自身.这包括clone(),equals(),hashCode()和toString()方法.实现可以可选地处理自引用场景,但是大多数当前实现不这样做.

关于为什么要包含这一段,我有点困惑.是因为Java7不能拥有直接或间接包含自身集合的自引用实例吗?然后Java8引入了新的界面或一些允许的新功能?

我正在寻找详细的解释,如果你举一个例子来说明你的观点,那将会很棒.谢谢!

Bri*_*etz 6

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在某些情况下,实现试图防止一些核心方法的这个问题; 这就是本段所说的.

  • 它说,[(本集合)] (2认同)

dav*_*xxx 5

是因为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实现通常不解决它,并且有意义,因为必须避免隐藏错误的客户端代码的故障,否则问题永远不会被解决.

"实现可以选择性地处理自引用场景,但是大多数当前的实现都不会这样做."

  • 欢迎:)当你将一个`String`连接到一个未被声明为`String`的对象(包含文字字符串)时,就像这里``Parent [childs ="+ childs +"]"`编译器应用` String.valueOf(Object)`这些对象中的每一个的方法.所以它最终被解释为``Parent [childs ="+ String.valueOf(childs))+"]"`````parent [childs ="+ childs.toString()+"]"`奖励not null检查`childs`以防止`NullPointerException`. (2认同)
  • 没问题:)`toString()`方法在`Object`类中声明.如果它继承自另一个类,则每个类都隐式或间接地扩展`Object`.所以扩展所有类"实现"`toString()`或者更确切地说:继承`toString()`方法. (2认同)