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."