@ExtensionMethod – Lombok’s feature in practice

Gaining of knowledge

In Java programming, we often use utility classes to handle repetitive operations, like text manipulation or mathematical calculations. These methods are usually static and called with class names, which can make the code less readable. However, Lombok offers an interesting feature called @ExtensionMethod, allowing you to treat static methods as instance methods. This makes the code cleaner and easier to read.

@ExtensionMethod is an annotation in Lombok that allows adding new functionality to existing classes based on static methods from utility classes. With this, you can use utility methods as if they were instance methods of a specific class.

Without @ExtensionMethod

In the traditional approach, you have to call utility class methods directly, for example:

import java.util.Objects;

public class Example {
    public static void main(String[] args) {
        String input = null;

        // Using the Objects class
        if (Objects.isNull(input)) {
            System.out.println("Input is null");
        }
    }
}

With @ExtensionMethod

With the annotation, the same code becomes more concise:

import lombok.experimental.ExtensionMethod;
import java.util.Objects;

@ExtensionMethod(Objects.class)
public class Example {
    public static void main(String[] args) {
        String input = null;

        // Calling Objects.isNull() as an instance method
        if (input.isNull()) {
            System.out.println("Input is null");
        }
    }
}

Here, the method Objects.isNull() is added to the String type, allowing a more natural usage like input.isNull().

How @ExtensionMethod Works

During compilation, Lombok automatically generates code that replaces instance method calls with corresponding static method calls from the utility class. While the syntax becomes more readable, the performance remains unaffected.

Extending Multiple Classes at Once

You can extend multiple utility classes simultaneously, which helps handle complex scenarios consistently.

import lombok.experimental.ExtensionMethod;
import java.util.Objects;
import java.util.Arrays;

@ExtensionMethod({Objects.class, Arrays.class})
public class MultiUtilityExample {
    public static void main(String[] args) {
        String input = null;
        int[] numbers = {1, 2, 3};

        // Using Objects.isNull()
        if (input.isNull()) {
            System.out.println("Input is null");
        }

        // Using Arrays.toString()
        System.out.println(numbers.toString());
    }
}

Practical Use Case

Imagine you need to check if input data is empty while also performing operations on arrays of numbers. With @ExtensionMethod, this can be done easily and in a clean way.

Code without @ExtensionMethod

import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.collections4.CollectionUtils;

public class Validator {
    public static void main(String[] args) {
        String input = "  ";
        List<String> items = List.of();

        if (StringUtils.isBlank(input)) {
            System.out.println("Input is blank");
        }

        if (CollectionUtils.isEmpty(items)) {
            System.out.println("List is empty");
        }
    }
}

Code with @ExtensionMethod

import lombok.experimental.ExtensionMethod;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.collections4.CollectionUtils;
import java.util.List;

@ExtensionMethod({StringUtils.class, CollectionUtils.class})
public class Validator {
    public static void main(String[] args) {
        String input = "  ";
        List<String> items = List.of();

        // Using @ExtensionMethod makes the code shorter
        if (input.isBlank()) {
            System.out.println("Input is blank");
        }

        if (items.isEmpty()) {
            System.out.println("List is empty");
        }
    }
}

Best Practices

  1. Use it wisely: Avoid overusing @ExtensionMethod to keep the code understandable.
  2. Keep it intuitive: Extend only methods that are simple and widely understood.
  3. Avoid conflicts: Make sure there are no naming conflicts between methods from different utility classes.

Using @ExtensionMethod does not affect performance because the annotation generates the necessary method calls during compilation. This is purely a syntactic improvement, and the generated code runs as efficiently as traditional static method calls.

Lombok’s @ExtensionMethod is a powerful tool that simplifies Java code, making it more natural and readable by eliminating repetitive static method calls. However, it’s important to use this feature with care to ensure the code remains clear and easy to maintain.

See more at https://projectlombok.org/

Leave a Reply

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