I really enjoy writing and reading lambda expressions – they’re succinct, expressive and fashionable (come on, like that doesn’t matter a little!). Compare that to anonymous classes which are neither of those things. Which is why I like to get rid of them!

This realization slowly materialized itself over the last months and yesterday my subconscious barfed up an idea of how to achieve that. I’ll present it here and follow up with a post in a couple of weeks after trying it out.

Overview

To make sure everybody knows what we’re talking about I’ll start with a quick recap on anonymous classes. I will then explain why I’d like to get rid of them before identifying their last stronghold and how to conquer it.

Quick Recap Of Anonymous Classes

Anonymous classes are used to create an ad-hoc implementation of an interface or an abstract class, like so:

Runnable run = new Runnable() {
	@Override
	public void run() {
		runThisThing(someArgument);
	}
};

This does indeed create a separate class (you will find it’s .class file next to the one which contains this code) but since it has no name, you guessed it, it’s called an anonymous class.

My opinion on the matter was always that these classes should be really short. One, maybe two methods with a couple of lines. Everything longer and definitely everything with state seems to deserve a name and a place of its own – either at the bottom of the file as a nested class or even as one of its own. It always confuses me to read methods which at some point create a 10+ line implementation of who-knows-what which does something totally unrelated.

But for short implementations (as in the example above) anonymous classes were the best choice.

getting rid of anonymous classes

Published by Mattia Notari under CC-BY-NC-SA 2.0.

So What’s Wrong With Them?

Nothing’s really wrong with them. It’s just that after about a year of using lambda expressions and method/constructor references they seem so incredibly clunky. The more I’m used to one-liners which express their behavior succinctly and precisely, the more I feel repulsed when being confronted with the ceremony and obfuscation of anonymous classes.

Just compare this to the example above:

Runnable run = () -> runThisThing(someArgument);

Over the last months I slowly realized that I just don’t wanna see them anymore and yesterday a nice little idea of how to get rid of the (up to know) necessary remaining occurrences popped into my head.

Getting Rid Of Anonymous Classes

As described above, I think everything more complicated than a simple implementation of one or two methods should generally get its own name and place as a nested or stand-alone class.

(By the way, I tend to do the same with classes that override an existing superclass method to change its behavior. This might be short but spotting the difference and deducing the intend is generally hard if you don’t know the now overridden original code. Giving the class a nice name solves this in most cases.)

Then of course Java 8 came around and thanks to lambda expressions, a huge number of use cases for anonymous classes just disappeared. This is great! And it is also the tool to get rid of their last stronghold: implementations of “almost-functional” interfaces and of abstract classes with one or two abstract methods.

So here’s my idea:

When coming across an interface or an abstract class which lends itself to be implemented ad-hoc, we create a functional implementation. This is a non-abstract class which delegates all method calls to functional interfaces which were specified during construction.

Example

I guess an example will clarify this:

public interface ValueListener<T> {

	void invalidated(T formerValue);

	void changed(T formerValue, T newValue);

}

Since this is no functional interface, you can not use lambda expressions to create an implementation. Instead you might create an anonymous class whenever you need one:

ValueListener<String> anonymousListener = new ValueListener<String>() {

 @Override
 public void invalidated(String formerValue) {
 valueInvalidated(formerValue);
 }

 @Override
 public void changed(String formerValue, String newValue) {
 valueChanged(formerValue, newValue);
 }
};

Instead we can once create a functional implementation of the interface:

public class FunctionalValueListener<T> implements ValueListener<T> {

 private final Consumer<T> invalidated;
 private final BiConsumer<T, T> changed;

 public FunctionalValueListener(
 Consumer<T> invalidated,
 BiConsumer<T, T> changed) {
 this.invalidated = invalidated;
 this.changed = changed;
 }

 @Override
 public void invalidated(T formerValue) {
 invalidated.accept(formerValue);
 }

 @Override
 public void changed(T formerValue, T newValue) {
 changed.accept(formerValue, newValue);
 }

}

Instances of this class can be created much more succinctly and less obfuscated:

ValueListener<String> functionalListener = new FunctionalValueListener<>(
 this::valueInvalidated,
 this::valueChanged);

Another Example

What actually triggered this idea were the many anonymous implementations of Swing’s AbstractAction I see in our code base:

Action action = new AbstractAction() {
	@Override
	public void actionPerformed(ActionEvent e) {
		performedAction(e);
	}
};

This screams “LAMBDA EXPRESSION!” but you can’t use it on abstract classes. But after creating a functional implementation which only requires aConsumer<ActionEvent> you can and it looks like this:

Action action = new FunctionalAction(this::performedAction);

Much better, right?

Follow Up

I will try this out for some weeks and report back how it worked. I already see some problems (arity of functional interfaces provided by the JDK and exceptions) and at least one way to improve this pattern.

But I think it is worth discussing this approach. If you think so, too, why don’t you share it?

Getting Rid Of Anonymous Classes

About The Author
- Nicolai is a thirty year old boy, as the narrator would put it, who has found his passion in software development. He constantly reads, thinks, and writes about it, and codes for a living as well as for fun. Nicolai is the editor of SitePoint's Java channel, writes The Java 9 Module System with Manning, blogs about software development on codefx.org, and is a long-tail contributor to several open source projects. You can hire him for all kinds of things.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>