Get a quick overview of how Lombok reduces boiler-plate code
Get a quick overview of how Lombok reduces boiler-plate code
We tend to write a lot of similar code in our projects for various purposes. We’d need to add constructors for our classes, getter & setter methods for our fields & other utility methods like for printing out an object directly using some variation of print
.
These are perfectly essential use-cases. But, due to the repetitive nature of the tasks, we can reduce the time we take on these if we follow some conventions.
Get a quick overview of how Lombok reduces boiler-plate code
We tend to write a lot of similar code in our projects for various purposes. We’d need to add constructors for our classes, getter & setter methods for our fields & other utility methods like for printing out an object directly using some variation of print
.
These are perfectly essential use-cases. But, due to the repetitive nature of the tasks, we can reduce the time we take on these if we follow some conventions.
You can download the source code from here using one of the following commands:
git clone https://gitlab.crio.do/crio_bytes/lombok.git
git clone git@gitlab.crio.do:crio_bytes/lombok.git
Verify by running Main.java
, you’ll see Running Completed outputted in the terminal
I have a Trade
class with some variables declared. I’m trying to create a new instance of Trade
class like this
Trade trade = new Trade("AAPL", 50, LocalDate.now());
While running the Main
class, the compiler is giving me some "Constructor is not defined" error. Can you help me make that go away?
(Verify by uncommenting the code in Main
class as instructed)
public class Trade {
private String symbol;
private int quantity;
private LocalDate purchaseDate;
}
Thanks. Now, I’m able to create new Trade
objects. But, there’s a new issue now. I’m having trouble retrieving & updating the values of the variable for objects of this class. Google told me I have to define getter & setter methods for private
variables as they are "private" for the class defining it.
It would be great if you could do that for me. I’d like to have the ability to access & modify all these private variables.
Nice! I’m going crazy modifying Trade
’s "private" variables. I’m hearing someone saying, “Privacy intrusion detected”.
Are you able to run the commented code in the Main
class to run without errors? Did you name the getter/setter methods something like getSymbol()
in the first place?
You can also try to override the toString()
method to be able to directly print a Trade
object like this using System.out.println()
Trade [purchaseDate=2020-06-12, quantity=1000000, symbol=GOOGL]
With all these done, how many lines of code does the Trade
class have? Can you scroll up to see how many lines we started with? How do you think the number of lines will increase with the number of variables?
Let’s say you are planning to create a REST API for a food delivery app. I’ve provided some of the classes you'll need inside src/main/java/com/example/lombok/dto
. Take a quick glance at those. How much time will you need to add the constructor/setter/getter/toStrings methods? How many lines of code?
(Quick note if you are highly adventurous: don’t get started with adding those methods. Save it for the next milestone!)
Trade
object? It should give an error, right?Lombok provides annotations (yeah, the things we put on top of classes/fields) for auto-generating boiler-plate code. This is achieved by injecting in the required things directly to the .class
files.
We’ll go popping out code in the order we added it (Okay, okay. You added it :) ) from Trade
class. Remove/comment out related code once you add the annotations.
Use @ToString
to auto-generate toString()
implementation
Use @Getter
/@Setter
to auto-generate getters & setters on either the class itself or on all of the fields you need a getter/setter
Use @AllArgsConstructor
to generate a constructor with all the parameters
Ok, quick question - how many lines of code does your Trade
class have now? If you were to add these to the classes in the dto
folder as well, how does it compare with what you were doing earlier?
Very cool, right? Can we do even better?
If you said, "What!", let’s understand how Lombok was able to reduce boiler-plate code. For @ToString
it sticked to a particular format printing out all the variables like this:
Trade [purchaseDate=2020-06-12, quantity=1000000, symbol=GOOGL]
With @Getter
/@Setter
at the class level, Lombok chose to create public
getters/setters for all non-static fields with standard naming convention like getSymbol()
. As for @AllArgsConstructor
, it creates a constructor with all the arguments in the order they were declared.
By sticking to certain specific cases (or restrictions), Lombok made it possible to reduce boiler-plate code. Coming back to our earlier challenge if this can be further reduced, it’s again a Yes!
@Data
do all these. Can you try adding the annotation? I’ve provided another class TradeData
if you like to keep your earlier code. What happens when you create a TradeData
instance in the Main
class? All well?
Sorry, I tricked you. No, no! @Data
does the work for us. There’s a slight difference
@Data = @ToString + @Getter/@Setter + @RequiredArgsConstructor
Check out how @RequiredArgsConstructor
works here.
We’ll need to annotate "required" arguments to be included in the constructor. You’ll have to find the annotation to be used.
Remove any Lombok annotations. Can you use the empty arguments constructor (new Trade()
) now? Add @AllArgsConstructor
and check again. Why do you think that happens?
Can you give a scenario when @RequiredArgsConstructor
functions like @NoArgsConstructor
for a class with non-zero fields?