class tree { int item; tree left; tree right; int size() { int size = 1; if (left!=null) size += left.size(); if (right!=null) size += right.size(); return size; } void benasty() { this.left = this; } // look ma, this compiles! } public class nasty { public static void main(String[] av) { tree t = new tree(); t.item = 5; t.benasty(); // look ma, this runs too! System.out.println("look at my tree of size: "+t.size()); } } // There's nothing in the Java language that's quite analogous to // std::unique_ptr in modern C++, which allows you to build a proper tree // as a directed acyclic graph. The tradeoff here is that the programmer // must think in terms of acyclic graphs instead of arbitrary graphs. // When java's garbage collector runs, it will be able to collect your // "nasty" tree without going into a loop precisely because the garbage // collector builds a SPANNING TREE. The modern C++ programmers who follow // the unique pointer protocol are building the TREE themselves in the first // place. // The limitation of unique_ptr is that sometimes there's a need to have // multiple pointers to the same object. It's not possible to build // a doubly linked list using unique_ptr. You will need share_ptr and // weak_ptr. This limitation exists even in Rust. (but then again, // you should be using a circular queue instead of a doubly linked list!)