Java 8 vs Java7 Collection Interface: self-referential instance

I read the documentation on the Java8 collection interface. I noticed that the Java8 Collection Interface added this paragraph to a description that is not included in the Java7 Collection Interface .

Some collection operations that perform recursive traversal collection may fail with the exception for self-referencing instances where the collection directly or indirectly contains itself. This includes the clone (), equals (), hashCode (), and toString () methods. Implementations may not necessarily handle the self-reference scenario, but most modern implementations do not.

I am a little confused because this paragraph is included. Is this because Java7 cannot have self-referencing instances in which the collection directly or indirectly contains itself? Then Java8 introduced a new interface or a new feature that allows this?

I am looking for detailed explanations, and it will be great if you include an example to illustrate your point. Thanks!

+5
source share
2 answers

Is this because Java7 cannot have self-referential instances where the collection directly or indirectly contains itself? Then Java8 introduced a new interface or new feature that allows what?

I do not think so. Prior to Java 8, instances can, of course, have their own reference.
And using them in Collection can, of course, create endless loops and crash at runtime with a StackOverflowError throw.

Here are two classes in which instance fields have circular dependencies between them, and the toString() method of each class relies on its own fields.

Parent that references Child:

 public class Parent { private List<Child> childs; public Parent(List<Child> childs) { this.childs = childs; } @Override public String toString() { return "Parent [childs=" + childs + "]"; } } 

A child who refers to a parent:

 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 + "]"; } } 

Suppose you are now creating a child and its parent:

 List<Child> childs = new ArrayList<>(); Child child = new Child(); childs.add(child); Parent parent = new Parent(childs); child.setParent(parent); 

Now you can call:

 parent.toString(); child.toString(); 

or in a Collection instance, for example:

 childs.toString(); 

You will get exactly the same result: java.lang.StackOverflowError

when a child invokes a parent that invokes a child that invokes a parent, etc.

The dock was probably updated using Java 8 to provide a risk of implementing these methods in a fragile way, since Collection implementations usually do not handle it, and it makes sense because hiding the failure to work with the code of the failed client otherwise the problem will never will be resolved.

"Implementations may not necessarily handle the self-referral scenario, but most modern implementations do not."

+5
source

The format toString() for List ; it must recursively toString() contents and display them in a comma-separated list limited to [ ... ] . If you create a List as follows:

 List<Object> list = new ArrayList<>(); list.add(list); System.out.println(list); 

a naive implementation of toString() will throw a StackOverflowError (try). Collection implementations try to protect against this problem for some basic methods, in some cases; what is said in this paragraph.

+6
source

Source: https://habr.com/ru/post/1270977/


All Articles