Core Java

Java Extension Methods

Whither Extension Methods?

Apparently, there’s a java dialect called XTend which does this, but there’s no obvious equivalent of extension methods in Java.

An extension method, as I recall from C#, allows you to define something like this:

01
02
03
04
05
06
07
08
09
10
11
int myExtensionMethod(SomeClass theExtendee, Object input) {
   return ...;
}
SomeClass myExtendable = new SomeClass();
// I'm calling this as though it's a member of the class
myExtendable.myExtensionMethod(someInput);
// as opposed to calling it as a wrapper
myExtensionMethod(myExtendable, someInput);

You can do the second of these in Java, and why wouldn’t you!?

Reusability in Streams

In a Java stream, we use a lovely fluent syntax. Let’s consider the following example:

1
2
3
4
5
6
Stream<String> someValues = someSource().stream()
    .map(Source::getParticularField)
    .map(Field::getParticularChild)
    .map(Object::toString)
    .filter(not(String::isBlank))
    .map(String::toUpperCase);

The above algorithm is in three phases:

  • Select the source of data
  • Drill down into the particularChild object
  • Convert to non-blank string rendered in upper case

The latter two of these might be turned into reusable components:

01
02
03
04
05
06
07
08
09
10
public static Stream<Child> drillDown(Stream<Source> source) {
    return source.map(Source::getParticularField)
        .map(Field::getParticularChild);
}
public static <T> Stream<String> nonBlankUppercase(Stream<T> source) {
    return source.map(Object::toString)
        .filter(not(String::isBlank))
        .map(String::toUpperCase);
}

The problem with this is that using them looks like it’s going to involve some nesting:

1
2
Stream<String> someValues = nonBlankUppercase(
    drillDown(someSource().stream()));

Not only is that a bit hard to read, but it’s backwards, compared with the nice fluent/forwards nature of the original.

We Can Solve This Via Streams Though!

It occurred to me today, though, that this can be solved via streams in Java. It’s definitely worth considering other ways that streams and Optional’s stream-like interface can make us compose transformations fluently:

1
2
3
Stream<String> someValues = someSource().stream()
    .flatMap(item -> drillDown(Stream.of(item)))
    .flatMap(item -> nonBlankUppercase(Stream.of(item)));

This is nearly in the category of useful…

Extensions would be better, though…

Published on Java Code Geeks with permission by Ashley Frieze, partner at our JCG program. See the original article here: Java Extension Methods

Opinions expressed by Java Code Geeks contributors are their own.

Ashley Frieze

Software developer, stand-up comedian, musician, writer, jolly big cheer-monkey, skeptical thinker, Doctor Who fan, lover of fine sounds
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
HelloWorld
HelloWorld
2 years ago

Hello World!
An extension method in C# is held in a static class. It is itself a static method. What makes it an extension method is the use of the this keyword on the 1st parameter. The type of this 1st parameter indicate what type will get that extension method available.
There is not additional parameter needed. Should there be any, they become sequentially the parameters of the extension method.
Hope this helps.

Back to top button