Re: Anonymous class - I don't know how to...
On Jun 28, 6:15 pm, r...@zedat.fu-berlin.de (Stefan Ram) wrote:
Andreas Leitgeb <a...@gamma.logic.tuwien.ac.at> writes:
final. Why?
The reasons are perhaps more technical than anything else.
=BBGuy Steele wrote:
Actually, the prototype implementation *did* allow
non-final variables to be referenced from within inner
classes. There was an outcry from *users*, complaining
that they did not want this!=AB
http://madbean.com/2003/mb2003-49/
And they got it anyway. See elsewhere in this thread -- Java
effectively *does* have closures, via the one-element-array trick and
exception abuse.
(Storing the closure and executing it after the enclosing function
exited of course results in a runtime exception bubbling up elsewhere
in the code and probably blowing everything up, but that's only proper
-- closures that return from their enclosing function are not meant to
be stored and executed after that function returns, and doing this
anyway is a bug and *should* therefore blow up the application with a
runtime exception stack trace as its final testament, just as invoking
a method on null does. The major issue is that really the exception
should be unique to each instance of the enclosing function being
executed. This can in effect be done, if you make a RuntimeException
in the enclosure:
public int enclosure () {
final RuntimeException throwme = new RuntimeException();
final int result[] = new int[0];
...
Runnable closure = new Runnable () {
public void run () {
...
if (someCondition) {
result[0] = something;
throw throwme;
}
...
}
}
...
try {
doSomethingWith(closure);
} catch (RuntimeException e) {
if (e == throwme) return result[0];
throw e;
}
}
The specific exception constructed for this invocation of enclosure is
compared for identity with the caught exception. If it's not the exact
same object the exception is simply rethrown, so the enclosure method
does not improperly eat any exception that should be handled elsewhere
or abort the program. Including even a closure returning from lexical
scope after its embedding function had already returned. Including
even the closure in "enclosure" doing so, and then trying to return,
and this managing to happen inside the try block during a later call
to "enclosure".
Of course, you'll probably not believe me if I tell you that Java also
has optional method parameters with defaults and keyword syntax.
Right? I knew it! You don't believe me.
public void function (Map args) {
Integer numFoos = (Integer)(args.get("numFoos"));
if (numFoos == null) numFoos = (Integer)(defaults.get("numFoos"));
int nFoos = numFoos.intValue();
Runnable doOnFail = (Runnable)(args.get("doOnFail"));
if (doOnFail == null) doOnFail = (Runnable)
(defaults.get("doOnFail"));
Integer maxFoos = (Integer)(args.get("maxFoos"));...
...
if (nFoos > mxFoos) doOnFail.run();
...
}
Map futz = new HashMap ();
futz.put("numFoos", Integer.valueOf(3));
function(futz);
Still don't believe me? :)