 |
The Good, The Bad, and The Ugly
Posted by evanx on October 10, 2006 at 07:55 AM | Comments (5)
In Concise Instance Creation Expressions: Closures without Complexity
by Bob Lee, Doug Lea, and Josh Bloch, they propose the following syntax
for closures, as a shorthand notation for anonymous classes with a single abstract method type,
eg. Runnable, Comparator and the like.
List<String> stringList = ... ;
Collections.sort(stringList,
Comparator<String>(String s1, String s2) {
return s1.length() - s2.length();
}
);
At first i thought why not include the method name as follows, for clarity.
Collections.sort(stringList,
Comparator<String>.compareTo(String s1, String s2) {
return s1.length() - s2.length();
}
);
Then i remembered, i just prefer the old familiar anonymous classes, and i'm not much
interested in shorthand.
Take abbreviations for instance. Abbreviation is the Clarity-Killer, which passes through
you and all that remains is Confusion. Programmers, that don't use IDEs, are not lazy enough!
And inconsiderate. They leave a trail of broken windows like abbreviations and
inconsistent names, and code in need of refactoring, which they can't fix - because
they don't use IDEs! That's why not using IDEs is the root of all evil ;)
Anyway enough of that nonsense. Let's consider Swing event handlers.
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
okActionPerformed();
}
});
The following shorthand would avoid the method declaration.
okButton.addActionListener(new ActionListener().actionPerformed(ActionEvent e) {
okActionPerformed();
});
And the following is as shorthandish as one could possibly make it, as in the above-mentioned
proposal.
okButton.addActionListener(ActionListener(ActionEvent e) {
okActionPerformed();
});
Considering that in Matisse, Netbeans generates and hides this code, and in general IDEs
generate anonymous class methods for you, to save those keystrokes, is there really a need
for such a shorthand notation? It goes towards having multiple
ways to do the same thing (The Bad), and towards less keystrokes for IDEA-less Clarity Killers
(The Ugly), and anyway what's wrong with anonymous classes (The Good, The Verbose and The Clear)?
Bookmark blog post: del.icio.us Digg DZone Furl Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment
-
would the Comparator interface actually fall into this one method category? Im looking at the interface and it declares an equals method. Granted, every object and its mother has an equals method...
Im not sure what to think about this. It looks like it saves me some indentation and brackets. On the other hand....
leouser
Posted by: leouser on October 10, 2006 at 08:13 AM
-
By the way, that Action should be ActionListener innit. leouser, i guess the compiler could look for a single abstract method - if there are more than one abstract methods declaret then it would have to throw a compilation error.
Posted by: evanx on October 10, 2006 at 08:20 AM
-
Shorthand for specifying anonymous classes for this like you describe here is one thing, but closures are different; they have the same (more or less) scope as the scope in which they are defined.
For interfaces with one public method, I prefer the first syntax. Actually, this is more concise:
Collections.sort(stringList, (String s1, String s2) { return s1.length() - s2.length(); } );
The compiler should be able to work out the type of the anon class from that.
Better yet:
stringList.sort { |s1,s2| s1.length <=> s2.length }
:-)
Posted by: goron on October 10, 2006 at 09:24 AM
-
Evan,
I use an IDE, but I see clearer the abbreviated syntax, because it expresses the same without redundant lines. I'm against shortening lines for the sake of saving space and decreasing readability, but I think this syntax is not an example of this, because this reduction only is valid for SAMs (Simple Abstract Method classes or interfaces), so the method's name is not necessary (the method used is the only one that needs to be defined).
The proposal also allows access to non-final variables out from the scope of the method, so it's not only the abbreviated syntax what you get.
I think this proposal makes very small changes, in the spirit of the Java language (not adding too much complexity) but improving it.
Regards,
- Xavi
Posted by: xmirog on October 11, 2006 at 12:24 AM
-
This looks nice and does indeed tidy code and make life easier but isn't it laying traps for the unwary newcomer ? Consider:
jbutton.addActionListener( ActionListener(ActionEvent ae) { foo(); } );
It's not by default obvious that what is being created here is a new instance of an ActionListener. Ask yourself what the home learner who sees this for the first time is going to think it does. A VB programmer (for instance) coming to java and seeing this might get the idea that ActionListener is a command. Whereas:
jbutton.addActionListener( new ActionListener(ActionEvent ae) { foo(); } );
Makes it much clearer what is being constructed is a new instance. But it could still fool the newcomers into thinking that it's constructing an ActionListener with an ActionEvent. I prefer the original suggestion of :
jbutton.addActionListener( new ActionListener().actionPerformed(ActionEvent ae) { foo(); } );
This shows that you are constructing a new ActionListener and that it's overriding or implementing a method. It reduces clutter but doesn't hide too much of whats going on. We must take care when improving Java that we don't steepen the learning curve ..
Posted by: luggypm on October 11, 2006 at 01:58 AM
|