3 Lombok Features Every Java Developer Must Know

7 min read
May 28, 2024
Photo by Alexandre Perotto on Unsplash

As Java developers, we're certainly familiar with Lombok and have indeed utilized it in our work.

Every now and then, we wish Lombok would simplify our code, but at times, we also worry it might complicate readability. Striking the right balance is crucial.

However, today, I feel the need to disrupt this balance.

In this article, we’ll explore the fascinating attractions that Lombok has to offer. Let’s go.

1 . @Delegate

@Delegate lets your class utilize methods from different classes without the need to write those methods yourself.

For instance, suppose you have a class called A with a method named sayHello(). If you'd like another class B to access this method, you can introduce a field of type A within class B. By annotating this field with @Delegate, class B will be able to invoke the sayHello() method directly, as if it were its own method.

See an example:


public class A {

public String sayHello(String name) {
return "Hello " + name;
}

}

public class B {
@Delegate
private A a = new A();

public String sayHello2(String name) {
return sayHello(name) + ". My name is Malvin.";
}
}

Here's what the .class file looks like after being compiled:

public class B {
private A a = new A();

public B() {
}

public String sayHello2(String name) {
String var10000 = this.sayHello(name);
return var10000 + ". My name is Malvin.";
}

public String sayHello(final String name) {
return this.a.sayHello(name);
}
}

The main benefit of this writing approach is that it helps prevent overly deep or tightly linked class hierarchies, enhancing both the code's readability and maintainability.

2. @Cleanup

@Cleanup is capable of handling different resources that require proper release, like input and output streams, and it makes sure that the close method is invoked securely.

To use it, simply attach the declared resource with @Cleanup. For instance:

public class fileUtil {
public InputStream openFile(final String name) throws IOException {
@Cleanup InputStream in = new FileInputStream("some/file");
return in;
}
}

Here’s a look at the .class file once it has been compiled:

public class fileUtil {

public InputStream openFile(final String name) throws IOException {
InputStream in = new FileInputStream("some/file");

FileInputStream var3;
try {
var3 = in;
} finally {
if (Collections.singletonList(in).get(0) != null) {
in.close();
}

}

return var3;
}

}

With this approach, once your code has finished running, Lombok will handle calling the in.close() method within a try-finally block automatically, ensuring resources are released.

3. Combination of @Singular and @Builder

@Builder enables chaining constructs in your class, whereas @Singular simplifies the management of collection-type fields.

The @Singular annotation is applicable to fields that are of collection types. It automatically creates two methods: one for inserting an individual element and another for adding an entire collection.

You can link these two methods with other methods created by @Builder to set values for every field in your class.

See an example:

@Data
@Builder
public class Student {
private String name;
private int age;
@Singular
private Map<String, Integer> grades;
}


public class CalculateService {

public Student addStudent() {
return Student.builder()
.name("Malvin")
.age(28)
.grade("English", 100)
.grade("Math", 99)
.grades(Map.of("Chinese", 100, "Physics", 99))
.build();
}

}

However, we're skipping the .class file this time around, as it's quite intricate.

It’s clear that using the @Singular annotation offers the advantage of allowing you to add fields to a collection type without needing to manually create and initialize the collection object.

Moreover, when the build() method is invoked, collection fields created with the @Singular annotation are transformed into immutable collections, guaranteeing object invariance and thread safety.

You have the option to utilize the clear() method to empty the collection fields. For example:

public class CalculateService {

public Student addStudent() {
return Student.builder()
.name("Malvin")
.age(28)
.grade("English", 100)
.grade("Math", 99)
.claar()
.grades(Map.of("Chinese", 100, "Physics", 99))
.build();
}

}

Keep in mind that although Lombok offers numerous handy features, excessive or improper use can make the code hard to comprehend and manage.

As a result, it's crucial to consistently be careful when utilizing these features and thoroughly think about their consequences.

Read more in Tech