📜 ⬆️ ⬇️

Java Programmer Crib 10: Lombok

image

Lombok is a project to add additional functionality in Java using the source code change before Java compilation.

In essence, the Lombok project allows you to get rid of Java verbosity in most cases and stop writing huge sheets of code from heteros, setters, equals, hashcode and toString (yes, they are usually generated by the IDE, but the programmer still has to read and change) almost as brief as Kotlin, Scala or C #.
')
What is particularly pleasing, Lombok is very simple and easy to add to your project. If you, like me, like the principle of KISS, then I advise you to look at Lombok.

I also recommend that you look at other articles in the series , such as the latest Java SE8 cheat sheet.

Adding to projects is very simple, just add the usual dependencies:

Read more ...
Maven :

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

You can also (but it is not necessary to add a plugin for static compilers, if you need to analyze the code after compiling Lombok), see here

Gradle

 plugins { id 'net.ltgt.apt' version '0.10' } dependencies { compileOnly 'org.projectlombok:lombok:1.16.18' apt "org.projectlombok:lombok:1.16.18" } 

There are also plugins for Idea , Eclipse , etc. If you build Gradle or Maven, it will be collected without these plug-ins, but Idea / Eclipse will probably show errors when analyzing the code.

Commands and annotations:
Table
TitleDescriptionLombok Example
Java sample
@NonNullprocessing variables
which should not receive null
 public Example(@NonNull P p) { super("Hello"); this.name = p.getName(); } 

 public Example(@NonNull P p) { super("Hello"); if (p == null) { throw new NullPointerException("p"); } this.name = p.getName(); } 

@Getter /
@Setter
easy creation of getters and
setters
 @Getter @Setter private int age = 10; 

 private int age = 10; public int getAge() { return age; } public void setAge(int age) { this.age = age; } 

@ToStringdefining annotation before class,
to implement the standard toString method
 @ToString(exclude="f") public class Example 

 public class Example { @Override public String toString() { return ...; } 

@EqualsAndHashCodeeasy creation of Equals and HashCode methods
 @EqualsAndHashCode( exclude={"id1", "id2"}) public class Example { 

 public class Example { ... @Override public boolean equals(Object o) { ... } @Override public int hashCode() { ... } 

@NoArgsConstructor,
@RequiredArgsConstructor,
@AllArgsConstructor
creating an empty constructor,
constructor including all final fields
or constructor including all possible fields
 @RequiredArgsConstructor( staticName = "of" ) @AllArgsConstructor( access = AccessLevel.PROTECTED ) public class E<T> { 

 public class E<T> { private E(T description) { ... } public static <T>E<T> of( T description ) { return new E<T>(description); } 

@Datageneration of all utility methods
immediately replaces the @ToString, @EqualsAndHashCode,
Getter , Setter , @RequiredArgsConstructor
 @Data public class Example { private final String name; private int age; } 

Lot of code
 public class Example { private final String name; private int age; public Example( String name ) { this.name = name; } public String getName() { return this.name; } void setAge(int age) { this.age = age; } public int getAge() { return this.age; } @Override public String toString() { return ...; } @Override public boolean equals( Object o ) { .... } @Override public int hashCode() { ... } 


@Valuecreating immutable classes
analogue of Data, but for immutable classes
 @Value public class Example { private final String name; private int age; } 

Lot of code
 public class Example { private final String name; private final int age; public Example( String name, int age ) { this.name = name; this.age = age; } public String getName() { return this.name; } public int getAge() { return this.age; } @Override public String toString() { return ...; } @Override public boolean equals( Object o ) { .... } @Override public int hashCode() { ... } 


@Builderimplementation of the bulder pattern,
Singular - used for objects in
single copy (add item
in collections, etc.)
 @Builder public class Example { private String name; private int age; @Singular private Set<String> occupations; } 

a lot of code
 public class Example { private String name; private int age; private Set<String> occupations; Example( String name, int age, Set<String> occupations ) { this.name = name; this.age = age; this.occupations = occupations; } public static ExampleBuilder builder() { return new ExampleBuilder(); } public static class ExampleBuilder { private String name; private int age; private ArrayList<> occupations; ExampleBuilder() { } public ExampleBuilder name( String name ) { this.name = name; return this; } public ExampleBuilder age( int age ) { this.age = age; return this; } public ExampleBuilder occupation( String occupation ) { if (this.occupations == null) { this.occupations = new ArrayList<String>(); } this.occupations.add(occupation); return this; } ... public Example build() { Set<String> occupations = ...; return new Example(name, age, occupations); } @java.lang.Override public String toString() { ... } } } 


@SneakyThrowswrapper of checked exceptions
@SneakyThrows (
UnsupportedEncodingException.class)
public String utf8ToString (byte [] bytes) {
return new String (bytes, "UTF-8");
}
 public String utf8ToString(byte[] bytes) { try { return new String(bytes, "UTF-8"); } catch (UnsupportedEncodingException e) { throw Lombok.sneakyThrow(e); } } 

@Synchronizedeasy creation of synchronized blocks
 private final Object readLock = new Object(); @Synchronized public static void hello() { ...; } @Synchronized public int answerToLife() { ... } @Synchronized("readLock") public void foo() { ... } 

Lot of code
 private static final Object $LOCK = new Object[0]; private final Object $lock = new Object[0]; private final Object readLock = new Object(); public static void hello() { synchronized($LOCK) { ... } } public int answerToLife() { synchronized($lock) { ... } } public void foo() { synchronized(readLock) { ... } } 


@Logadding logging initiation,
also allows you to select the type of logger: @CommonsLog,
@JBossLog, Log , @ Log4j, @ Log4j2, @ Slf4j, @ XSlf4j
 @Slf4j public class Example { public static void main(String... args) { log.error("error"); } 

 public class Example { private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExampleOther.class); public static void main(String... args) { log.error("error"); } 

Valsimple creation of the final
variable with type inference,
that is, the val of which
argued
 val map = new HashMap<Integer, String>(); for (val entry : map.entrySet()) { ... } 

 final HashMap<Integer, String> map = new HashMap<Integer, String>(); ... for (final Map.Entry<Integer, String> entry : map.entrySet()) { ... } 

@Cleanupsimple definition of resources
so that they automatically close
after the end of the code.
(not so relevant when using
try with resources)
 @Cleanup InputStream in = new FileInputStream(args[0]); @Cleanup OutputStream out = new FileOutputStream(args[1]); ... 

 InputStream in = new FileInputStream(args[0]); try { OutputStream out = new FileOutputStream(args[1]); try { ... } finally { if (out != null) { out.close(); } } } finally { if (in != null) { in.close(); } } 





If the table seems poorly read, just take turns
Name: @NonNull
Description: handling variables
which should not receive null
Lombok code:
 public Example(@NonNull P p) { super("Hello"); this.name = p.getName(); } 
Common Java code:
 public Example(@NonNull P p) { super("Hello"); if (p == null) { throw new NullPointerException("p"); } this.name = p.getName(); } 



Name: Getter /
Setter
Description: easy creation of getters and
setters
Lombok code:
 @Getter @Setter private int age = 10; 
Common Java code:
 private int age = 10; public int getAge() { return age; } public void setAge(int age) { this.age = age; } 



Name: @ToString
Description: definition of annotation before class,
to implement the standard toString method
Lombok code:
 @ToString(exclude="f") public class Example 
Common Java code:
 public class Example { @Override public String toString() { return ...; } 



Name: @EqualsAndHashCode
Description: Easy creation of Equals and HashCode methods.
Lombok code:
 @EqualsAndHashCode( exclude={"id1", "id2"}) public class Example { 
Common Java code:
 public class Example { ... @Override public boolean equals(Object o) { ... } @Override public int hashCode() { ... } 



Title:
@NoArgsConstructor,
@RequiredArgsConstructor,
@AllArgsConstructor
Description: creating an empty constructor,
constructor including all final fields
or constructor including all possible fields
Lombok code:
 @RequiredArgsConstructor( staticName = "of" ) @AllArgsConstructor( access = AccessLevel.PROTECTED ) public class E<T> { 
Common Java code:
 public class E<T> { private E(T description) { ... } public static <T>E<T> of( T description ) { return new E<T>(description); } 



Name: Data
Description: generation of all utility methods,
immediately replaces the @ToString, @EqualsAndHashCode,
Getter , Setter , @RequiredArgsConstructor
Lombok code:
 @Data public class Example { private final String name; private int age; } 



 public class Example { private final String name; private int age; public Example( String name ) { this.name = name; } public String getName() { return this.name; } void setAge(int age) { this.age = age; } public int getAge() { return this.age; } @Override public String toString() { return ...; } @Override public boolean equals( Object o ) { .... } @Override public int hashCode() { ... } 




Name: Value
Description: creating immutable classes,
analogue of Data, but for immutable classes
Lombok code:
 @Value public class Example { private final String name; private int age; } 


Common Java code:
 public class Example { private final String name; private final int age; public Example( String name, int age ) { this.name = name; this.age = age; } public String getName() { return this.name; } public int getAge() { return this.age; } @Override public String toString() { return ...; } @Override public boolean equals( Object o ) { .... } @Override public int hashCode() { ... } 




Name: Builder
Description: implementation of the bulder pattern,
Singular - used for objects in
single copy (add item
in collections, etc.)
Lombok code:
 @Builder public class Example { private String name; private int age; @Singular private Set<String> occupations; } 


Common Java code:
 public class Example { private String name; private int age; private Set<String> occupations; Example( String name, int age, Set<String> occupations ) { this.name = name; this.age = age; this.occupations = occupations; } public static ExampleBuilder builder() { return new ExampleBuilder(); } public static class ExampleBuilder { private String name; private int age; private ArrayList<> occupations; ExampleBuilder() { } public ExampleBuilder name( String name ) { this.name = name; return this; } public ExampleBuilder age( int age ) { this.age = age; return this; } public ExampleBuilder occupation( String occupation ) { if (this.occupations == null) { this.occupations = new ArrayList<String>(); } this.occupations.add(occupation); return this; } ... public Example build() { Set<String> occupations = ...; return new Example(name, age, occupations); } @java.lang.Override public String toString() { ... } } } 




Name: @SneakyThrows
Description: Wrapped Check Exceptions
Lombok code:

@SneakyThrows (
UnsupportedEncodingException.class)
public String utf8ToString (byte [] bytes) {
return new String (bytes, "UTF-8");
}

Lombok code:
 public String utf8ToString(byte[] bytes) { try { return new String(bytes, "UTF-8"); } catch (UnsupportedEncodingException e) { throw Lombok.sneakyThrow(e); } } 



Name: @Synchronized
Description: easy creation of synchronized blocks
Lombok code:
 private final Object readLock = new Object(); @Synchronized public static void hello() { ...; } @Synchronized public int answerToLife() { ... } @Synchronized("readLock") public void foo() { ... } 


Common Java code:
 private static final Object $LOCK = new Object[0]; private final Object $lock = new Object[0]; private final Object readLock = new Object(); public static void hello() { synchronized($LOCK) { ... } } public int answerToLife() { synchronized($lock) { ... } } public void foo() { synchronized(readLock) { ... } } 




Name: Log
Description: adding logging initiation,
also allows you to select the type of logger: @CommonsLog,
@JBossLog, Log , @ Log4j, @ Log4j2, @ Slf4j, @ XSlf4j
Lombok code:
 @Slf4j public class Example { public static void main(String... args) { log.error("error"); } 
Common Java code:
 public class Example { private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExampleOther.class); public static void main(String... args) { log.error("error"); } 



Val simple creation of the final
variable with type inference,
that is, the val of which
argued
 val map = new HashMap<Integer, String>(); for (val entry : map.entrySet()) { ... } 

 final HashMap<Integer, String> map = new HashMap<Integer, String>(); ... for (final Map.Entry<Integer, String> entry : map.entrySet()) { ... } 



Name: @Cleanup
Description: A simple definition of resources.
so that they automatically close
after the end of the code.
(not so relevant when using
try with resources)
Lombok code:
 @Cleanup InputStream in = new FileInputStream(args[0]); @Cleanup OutputStream out = new FileOutputStream(args[1]); ... 
Common Java code:
 InputStream in = new FileInputStream(args[0]); try { OutputStream out = new FileOutputStream(args[1]); try { ... } finally { if (out != null) { out.close(); } } } finally { if (in != null) { in.close(); } } 

Source: https://habr.com/ru/post/345520/


All Articles