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. |
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.