ThreeStarProgramming in Java, from example listing 9.5 in the book Java Concurrency in Practice, ISBN 0321349601
private void longRunningTaskWithFeedback() { button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { button.setEnabled(false); label.setText("busy"); exec.execute(new Runnable() { public void run() { try { /* Do big computation */ } finally { GuiExecutor?.instance().execute(new Runnable() { public void run() { button.setEnabled(true); label.setText("idle"); } }); } } }); } }); }Three layers of inner classes. Don't try this at home, readers. Remember, we're experts.
How about an classloader that is an inner-class and uses variables from its enclosing scope:
The code above still looks markedly more scary. Maybe a distinction between a ThreeArrowJava? coder versus a ThreeStarJava coder?
[The degree of scariness of the above example may depend on the reader's familiarity with use of inner classes. I find the example very readable, and prefer it to what would be required without inner classes. (Of course, in that particular example, even better would be a ThreadSafe GUI API so such machinations wouldn't be needed.)]
I concur, though I would rather expect the GuiExecutor? to take two runnables, one for the actual job, and one for the finalization part. That way, I wouldn't have to explicitly redispatch the finalization into the GuiThread.
The finalization is required to be redispatched to the GuiThread because Swing is single-threaded.
{The scariness of the MethodFactory? comes from ClassLoader and reflection "magic" which is seldom used or restricted to some specialized framework behind the scenes. Whereas inner classes as such are daily business for the distinuished Java developer.}
{And as always this is only so unreadable because Java doesn't support compact closures. With a block notation it could like like this:}
private void longRunningTaskWithFeedback() { button.addActionListener([ActionEvent e| button.setEnabled(false); label.setText("busy"); exec.execute([ try { /* Do big computation */ } finally { GuiExecutor?.instance().execute([button.setEnabled(true); label.setText("idle");]); }]); ]); }
Should we call this "ThreeNestedInnerClassJavaProgrammers?"? ;->
The syntax is really nasty, but I don't find the above really scary. It would be nice to have closures, to fix the "syntactic gunk" problem.
You missed the obvious "ClassThreeProgrammer?"
You don't need to nest the inner classes. You could define three anonymous inner classes at method scope that refer to one another by variable name, or define three named inner classes that instantiate one another as appropriate. There are lots of ways to make that code more readable. Bingo! That's why I put the example here as ThreeStarJava. It doesn't have to be coded this way, although it might be idiomatic for some Java programmers.