Java Lombok Tutorial
What is Lombok?
Project Lombok is a java library tool which is used to minimize/remove the boilerplate code and save the developers time during development by using some annotations. We can plug into editor and provide a esay way to write lombok annotation. Lombok has a various annotations which can be used inside our Programs, that are checked during the compilation period, and an acceptable application extension will take place depending on the annotation used.
Why lombok, what is the need to use lombok?
Java is a very common language, but there are few disadvantages. One of the most common drawbacks is that we still need to write the boilerplate codes in Java such as getters, setters, toString method, whereas Kotlin and Scala, which are both based on JVM, do not need to do so and this is perhaps the reason for their increased community popularity. This is where Lombok comes into picture and overcomes this Java disadvantage.
Steps to install Lombok into Intellj
- Go to File > Settings > Plugins
- Click On Install
- Click on Restart
Steps to install Lombok into Eclipse
- Download lombok.jar.
- You can also use lombok jar from .m2 directory, once maven install lombok.jar.
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
<scope>provided</scope>
</dependency>
java -jar lombok.jar
. It will open below wizard.Lombok annotations:
Let's explore some Lombok Annotations.- @Getter and @Setter:
You can annotate any field with @Getter and/or @Setter to allow lombok to generate the default getter/setter automatically. These annotations can be used at both the levels, field as well as class. The generated getter/setter method will be public unless you specifically specify the AccessLevel (PUBLIC, PROTECTED, PACKAGE, PRIVATE).
import Lombok.Getter; import lombok.Setter; @Getter @Setter public class Notes { private Integer id; private String comment; }
- @NoArgsConstructor:
It generates a constructor with no parameters.
import lombok.NoArgsConstructor; @NoArgsConstructor public class Notes { private Integer id; private String comment; }
- @AllArgsConstructor:
This annotation generates a constructor with one parameter for each field in your class.
import lombok.AllArgsConstructor; @AllArgsConstructor public class Notes { private Integer id; private String comment; }
- @ToString:
@ToString annotation overrides the toString() method and provides default implementation of toString(). The default implementation prints the class name and the fields in order, separated by commas. You can skip some fields that you don't want to print by using @ToString.Exclude annotation on the fields.
import lombok.ToString; @ToString public class Notes { private Integer id; // this field get excluded in default toString() // and will not get print @ToString.Exclude private String comment; }
- @EqualsAndHashCode:
While creating a class, it is suggested to override the hashCode() and equals() methods. @EqualsAndHashCode annotation is used to injects code for equals() & hashCode() method in Lombok.
import lombok.EqualsAndHashCode; @EqualsAndHashCode public class Notes { private Integer id; private String comment; }
- @Data:
@Data annotation is a shortcut annotation and bundles @ToString, @Getter, @Setter, @EqualsAndHashCode and @RequiredArgsConstructor annotations into a single annotation.
import Lombok.Data; @Data public class Notes { private Integer id; private String comment; }
- @Builder:
Builder Pattern automatically produce the code required to have your class be instantiable using builder pattern.
@Builder can be placed on a class, or on a constructor, or on a method.
@Builder public class Notes { private Integer id; private String comment; private String name; public static void main(String[] args) { Notes notes = Notes.builder() .id(1) .comment("Added first note.") .name("abc") .build(); } }
- @SneakyThrows:
@SneakyThrows annotation used to sneakily throw checked exceptions without actually declaring this in your method's throws clause. Sometimes, while using some of JAVA Api's, it becomes mandatory/forced to catch or decalre to throw the exception in code. Like whenever using strict interface, such as Runnable, whatever exception propagates out of your run() method, checked or not, it will be passed to the Thread's unhandled exception handler. Catching a checked exception and wrapping it in some sort of RuntimeException is only obscuring the real cause of the issue.
Note: The code generated by lombok will not ignore, wrap, replace, or otherwise modify the thrown checked exception; it simply fakes out the compiler. Be conscious that it is impossible to explicitly catch sneakily thrown checked types, as javac will not let you write a catch block for an exception type that no method call in the try body declares as thrown. Let this serve as an alert that without some deliberation, you should not use the @SneakyThrows mechanism!
Plain Java
With Lombokpublic String readFile() { try (InputStream input = this.getClass().getResourceAsStream("note.txt")) { BufferedReader reader = new BufferedReader(new InputStreamReader(input, "UTF-8")); return reader.lines().collect(Collectors.joining("\n")); } catch (IOException | UnsupportedCharsetException ex) { throw new RuntimeException(ex); } }
@SneakyThrows public String readFile() { try (InputStream input = this.getClass().getResourceAsStream("note.txt")) { BufferedReader reader = new BufferedReader(new InputStreamReader(input, "UTF-8")); return reader.lines().collect(Collectors.joining("\n")); } }
- @Cleanup:
Java 7 implemented the try-with-resources block to ensure that instances of anything implementing java.lang.AutoCloseable are released upon exiting your resources. In Lombok, @Cleanup annotation offers an alternative way to do this, and more flexibly. Use it with every local variable that you want to make sure it releases it's resources. Simply use @Cleanup annotation which will call its close() method to release it's resources.
@Cleanup InputStream input = this.getClass().getResourceAsStream("note.txt");
- @Val:
Use val annotation for declaring the type of variable like we do in Java as given below.
import java.util.ArrayList; import lombok.val; // without lombok - List notes = new ArrayList<String>(); val notes = new ArrayList<String>(); // without lombok - Map noteMap = new HashMap<Integer, String>(); val noteMap = new HashMap<Integer, String>();
- @NonNull:
You can use @NonNull annotation on the parameter of constructor or a method to generate null check.
import lombok.NonNull; public class Notes { private @NonNull Integer id; private String comment; }
- @Value:
@Value introduced from lombok v0.12.0 to the main lombok kit.
In general, @Value is shorthand for @ToString @EqualsAndHashCode @AllArgsConstructor @FieldDefaults(makeFinal = true level = AccessLevel. PRIVATE) @Getter, Except that explicitly including the implementation of any of the relevant methods basically means that part will not be generated and no warning will be issued.
@Value is the immutable variant of @Data; all fields are made private and final by default, and setters are not generated. The class itself is also made final by default, because immutability is not something that can be forced into a subclass. Like @Data, useful toString(), equals() and hashCode() methods are also generated, each field gets a getter method, and a constructor that covers every argument (except final fields that are initialized in the field declaration) is also generated.
import Lombok.Value; @Value public class Notes { private Integer id; private String comment; }
- @Log:
You can write the @Log option on your class (whichever one corresponds to the logging method you are using); you then have a final static log field initialized as is the commonly prescribed way of logging the framework you are using, which you can then use to write log statements.
NEW in lombok v1.16.24: Addition of google's FluentLogger (via @Flogger).
SLF4J - Without Lombok
NEW in lombok v1.18.10: Addition of @CustomLog which lets you add any logger by configuring how to create them with a config key.
SLF4J - With Lombokpublic class Notes { private static Logger LOG = LoggerFactory.getLogger(Notes.class); // LOG.debug(), LOG.info(), ... }
import lombok.extern.slf4j.Slf4j; @Slf4j // other log annotations: @Log @CommonsLog @Flogger @JBossLog @Log @Log4j @Log4j2 @XSlf4j @CustomLog public class Notes { // LOG.debug(), LOG.info(), ... }
- @Synchronized:
@Synchronized is a safer type of the synchronized method modifier. This annotation can be use on methods (both instance and static) and it'll autogenerate private, unexposed field that your implementation will use for locking.
@Synchronized public void addComment(String id, Object value) { // thread-safe code }