Lombok – ExtensionMethod Annotation

Today I´d like to present to you a nice little feature of (Project) Lombok that will may impact on the way you work with static methods in Java.

Project Lombok is mostly known as a framework to avoid boiler plate code. I usually use lombok because I don´t want to write…

  • Setter
  • Getter
  • Constructors
  • Builder Pattern
  • Equals and Hashcode

…on my own.

The new annotation we will look on in this post also avoids writing boiler plate code, but isn´t (directly) attached on your entity.

The ExtensionMethod Annotation of Lombok enables you to call static methods directly on their related object value without the need of calling the (static) class itself.
Cause this sentence is a bit hard to understand without some code, have look at this.

Code Samples

Let´s write a little code example in which we look at how the Lombok Annotation works. Of course you can modify this example as much as you want to. In this example we have two heroes, which have an id, a name and a herotype.

Maven Dependency

First of all we need to add the Maven Dependency for lombok:

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.16.16</version>
</dependency>

Enum HeroType

Then we need the following little enum. We need this for in our implementation example

/**
 * 
 * @author javadevcorner.com
 */
public enum HeroType {
    SUPER_HERO,
    MATE;
}

Hero entity

After that, please create a little POJO of your choice. For me it is a little hero class

/**
 *
 * @author javadevcorner.com
 */
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Hero {

    private long id;
    private String name;
    private HeroType heroType;
}

HeroValidator class

As I mentioned, we need the enum HeroType because we want to implement a little behaviour based on this.

/**
 *
 * @author javadevcorner.com
 */
public class HeroValidator {

    public static boolean isHeroASuperHero(Hero hero) {
        return hero.getHeroType().equals(HeroType.SUPER_HERO);
    }
}

This Validator is also just a plain class.

AppStarter and the Lombok Magic

Now we come to the magic part of the Lombok Annotation. I´ll show you the code first and will explain to you what happens afterwards

import lombok.experimental.ExtensionMethod;

/**
 *
 * @author javadevcorner.com
 */
@ExtensionMethod({
        HeroValidator.class
})
public class AppStarter {

    public static void main(String[] args) {
        Hero batman = Hero
                .builder()
                .id(1)
                .name("Batman")
                .heroType(HeroType.SUPER_HERO)
                .build();
        Hero robin = Hero
                .builder()
                .id(2)
                .name("Robin")
                .heroType(HeroType.MATE)
                .build();

        System.out.println(batman.isHeroASuperHero());
        System.out.println(robin.isHeroASuperHero());

    }
}

Okay, lets get deeper in it:

  • Above AppStarter class declaration: We are annotating the HeroValidator via @ExtensionMethod
  • At first we are creating the two heroes batman and robin using the Builder Pattern
  • We just print out if hero is of type SUPER_HERO or not.

Your IDE may will mark the call of isHeroASuperHero() as not compilable. Trust me, it will work when you run the application

Look again at the HeroValidator class in special at the signature of the method.

public static boolean isHeroASuperHero(Hero hero)

The method awaits an input parameter of type hero. But we are calling the method without. That´s the magic of lombok. 
Because of the type of the first parameter in a method signature, lombok knows if the object calling the method can call it or not. 

Where and Why use @ExtensionMethod

Maybe the first thing that will come to your mind is something like:
Okay, nice, but why shouldn´t I just write the isHeroASuperHero(Hero hero) Method as a private method in AppStarter?
That´s good point – if you have other points I hope the following sentences will also answer them, otherwise feel free to comment or contact me.

This hero example is a very synthetic example to explain to you the behaviour of this @ExtensionMethod.

Where to use

Following some examples where I think you could use this approach:

  • Legacy code you can´t / won´t modify but need an additional method
  • Implement methods for final classes you can not extend (for example String)

Why you can use

The main reason for using this annotation is to make your code more sweet I think.
In my opinion it is easier to read what´s happening in the line of code and it is a bit of syntax candy.

Conclusion

We have looked at the Lomok @ExtensionMethod Annotation and how to use it. Furthermore we have discussed where we have some possible cases to use this annotation. Beyond this probed why you can use this annotation in your application.

 

So thanks for reading and have fun using The ExtensionMethod Annotation of Lombok.

Feel free to share

Leave a Reply

Your email address will not be published. Required fields are marked *

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