How far to go in replacing inner classes with lambdas?
Remi Forax
forax at univ-mlv.fr
Sun Oct 28 10:18:59 PDT 2012
On 10/28/2012 05:53 PM, Joshua Bloch wrote:
> Brian,
>
> I would stop at the first refactoring: I'm not convinced that the
> unbound method reference construct will /ever /look familiar. That
> said, neither of the refactorings is as easy to understand as the
> original code declaration. In the first, you loose the fact that the
> argument to an Executor's sole abstract method is of type Runnable.
> When you're dealing with two SAM types at once (Executor and Runnable
> in this case), things can get a bit confusing. The second refactoring
> does make the argument type (Runnable) explicit, but it's just
> unreadable.
>
> A casualty in both refactorings is the comment:
>
> // DirectExecutor using caller thread
>
> It's invaluable in keeping the code readable, and must be maintained.
>
> Josh
>
> P.S. While you're cleaning up the code, "final static" should be
> "static final."
Brian,
you can go a step further because either r -> r.run() or Runnable::run
are non capturing lambdas
thus they doesn't need to be stored in a static final field.
So you can replace
public NotificationBroadcasterSupport(Executor executor,
MBeanNotificationInfo... info) {
this.executor = (executor != null) ? executor : defaultExecutor;
...
}
by
public NotificationBroadcasterSupport(Executor executor,
MBeanNotificationInfo... info) {
// if the executor is null, the runnable is executed by the
current thread
this.executor = (executor != null) ? executor : r -> r.run();
...
}
You can apply the same idea to j.u.functions.Mappers and Predicates.
cheers,
Rémi
>
> On Sun, Oct 28, 2012 at 9:12 AM, Brian Goetz <brian.goetz at oracle.com
> <mailto:brian.goetz at oracle.com>> wrote:
>
> The IntelliJ EAP builds already have inspections for "replace
> inner with lambda" and "replace lambda with method reference"
> (nice job, guys!)
>
> In browsing through the inspection results in the JDK, we find
> ourselves in the same position we did with Coin features like
> Diamond; many code snippets can be simplified, but not all code
> snippets that can be simplified should be.
>
> Here's an example:
>
> private final static Executor defaultExecutor = new Executor() {
> // DirectExecutor using caller thread
> public void execute(Runnable r) {
> r.run();
> }
> };
>
> We could simplify this to:
>
> private final static Executor defaultExecutor = r -> r.run();
>
> or further to
>
> private final static Executor defaultExecutor = Runnable::run;
>
> (Executor is a SAM interface with one method, execute(Runnable).)
>
>
> What guidelines can we offer users on when they should and should
> not replace inner classes with lambdas or method reference? Does
> this last one look a little weird only because the powerful
> "unbound method reference" construct is still a little unfamiliar?
>
>
More information about the lambda-libs-spec-observers
mailing list