In JavaScript a nested type can read and assign variables from outer scopes.
function counter(start = 0) {
let n = start;
class Counter {
peek() { return n; }
increment() { ++n; }
}
return new Counter();
}
In Java, a nested type can read effectively final locals, but cannot read or set mutable locals because the Java language people are loathe to convert portions of stack frames to objects, or reify stack frames in the JVM.
Counter counter(int start) {
int n = start;
class BadCounterImpl implements Counter {
public int peek() { return n; } // OK
public void increment() { ++n; } // ILLEGAL
}
// OK
class CounterImpl implements Counter {
// Capture by copy of effectively final int start
private int n = start;
...
}
return new CounterImpl();
}
These types exposed by returns and that have no fully qualified name are called Voldemort types because you cant say their name (At least D calls them that).