Lombok is a Java annotation-driven minimalist code tool that generates bytecode files by modifying the Abstract syntax tree (AST) at compile time.

Preparations:

  1. Add the dependent

    <dependency>

< the groupId > org. Projectlombok < / groupId > < artifactId > lombok < / artifactId > < version > 1.16.16 < / version > < / dependency >

2. Add the Lombok plug-in to the IDE, otherwise using Lombok annotations will generate errors at compile time.

A: val

Definition: A modifier of a local variable that determines the type by definition.

Example:

@Test public void testValExample() { val hello = “Hello World!” ; assertSame(hello.getClass(), String.class); assertEquals(hello, “Hello World!” ); }

Note:

  1. Can only be used when declaring local variables, not on class fields.

  2. Variables modified by val are themselves final and cannot be modified.

2: @ NonNull

Definition: Modifies a method, constructor parameter, or class field. Lombok automatically generates a non-null check statement.

We do not discourage passing null arguments to methods and recommend using Optional in JDK8 or Google Guava to avoid null arguments.

Example:

public class Example { public Example(@NonNull String something) { System.out.println(“do something in Example class : ” + something); }}


public class NonNullExample extends Example { public NonNullExample(@NonNull String something) { super(something); System.out.println(“do something in NonNullExample : ” + something); }}


@Test public void testNonNullExample() { try { NonNullExample nonNullExample = new NonNullExample(“say hello”); NonNullExample nullExample = new NonNullExample(null); }catch (NullPointerException e) { e.printStackTrace(); }}

Unit test results:

do something in Example class : say hello

do something in NonNullExample : say hello

java.lang.NullPointerException: something

at com.iqiyi.mp.lombok.Example.<init>(Example.java:10)

at com.iqiyi.mp.lombok.NonNullExample.<init>(NonNullExample.java:11)

at com.iqiyi.mp.test.LombokTest.testNonNullExample(LombokTest.java:28)

When a non-empty argument is passed in, the parent constructor is printed first, and then the subclass constructor is printed. When an empty argument is passed in, NLP is raised. We conclude that the nonnull detection that Lombok does in the subclass is done after the super statement.

Note:

  1. If (param == null) throw new NullPointerException(“param”), insert a statement at the beginning of the method or constructor.

  2. If @nonNULL is used in the constructor, non-null checks are inserted immediately after the super or this methods.

  3. Lombok does not repeat a non-null test if it has been explicitly done at the beginning of a method or constructor.

Three: log annotations.

Definition: Use @comonslog, @jbosslog, @log, @log4j, @log4j2, @slf4j, @xslf4j to determine which logging framework you want to use.

Example:

@Slf4j(topic = “HelloLombok”) public class LogExample { public void printLog() { log.info(“hello, lombok.”); }}

Unit tests:

@Test

public void testLogExample() {

    LogExample logExample = new LogExample();

    logExample.printLog();

}

Unit test results:

2017-03-26 22:41:11,374 [main] INFO  HelloLombok printLog 12 – hello, lombok.

Note:

  1. All log annotations uniformly use the log object for method calls.

  2. You can get a named Logger object via the Topic property; the default topic uses the class name.

4: @ the Cleanup

Definition: Add the @cleanup annotation to a local variable and Lombok will automatically close open resources.

Example:

@Test

public void testCleanupExample() throws IOException {

    @Cleanup

    InputStream in = new FileInputStream(“fileIn.txt”);

    @Cleanup

    OutputStream out = new FileOutputStream(“fileOut.txt”);

    byte[] b = new byte[10000];

    while (true) {

        int r = in.read(b);

        if (r == -1) break;

        out.write(b, 0, r);

    }

}

Note:

  1. In JDK7 or later, it is strongly recommended to use try-with-resources to close resources, which is the native automatic resource closing method in JDK.

  2. The resource is closed automatically by adding a try/finally block of code. The close method with no arguments is called by default.

  3. The method for cleaning up a resource is explicitly specified through the value attribute, but all methods for cleaning up a resource cannot have any arguments or they will not be called.

Five: @Getter and @Setter

Definition: Add @getter and @setter annotations for a field or class, Lombok automatically generates Getter and Setter methods.

Example:

public class GetterSetterExample {

    @Getter

    @Setter

    private String name;



    @Getter(AccessLevel.PROTECTED)

    @Setter(AccessLevel.PRIVATE)

    private int age;

}

Unit tests:

@Test

public void testGetterSetterExample() {

    val example = new GetterSetterExample();

    example.setName(“DBQ”);

    assertEquals(“DBQ”, example.getName());

}

Note:

  1. Access permission is controlled by AccessLevel. The default access permission is Public.

  2. Set AccessLevel access to NONE. Lombok does not generate Getter/Setter methods and can override Getter/Setter methods based on your business.

  3. Use @getter, @setter annotations on classes, and Lombok generates Getter/Setter methods for all non-static fields in that class.

Six: @ ToString

Definition: Add the @toString annotation to a class that Lombok automatically generates ToString methods for.

Example:

@ToString(exclude = “name”)

public class ToStringExample {

    private String name;

    private int age;

}

Unit tests:

@Test

public void testToStringExample() {

    val example = new ToStringExample();

    String result = example.toString();

    assertEquals(“ToStringExample(age=0)”, result);

}

Note:

  1. The @toString annotation defaults to printing a string like className(fieldName=fieldValue, fieldName=fieldValue).

  2. The includeFieldNames attribute in the @toString annotation, which defaults to true, explicitly outputs the field name, exclude, explicitly specifies the field to exclude, of, displays the field to output, callSuper, outputs the ToString method of the parent class, The doNotUseGetters property, which defaults to false, takes precedence over Getter methods if there are Getter methods in the code.

Seven: @ EqualsAndHashCode

Definition: Annotate a class with @equalSandHashCode. Lombok automatically generates equals and hashCode methods for non-static, non-transient fields.

Example:

@EqualsAndHashCode(exclude = “age”)

@AllArgsConstructor

public class EqualsAndHashCodeExample{

    private String name;

    private int age;

}

Unit tests:

@Test

public void testEqualsAndHashCodeExample() {

    val example = new EqualsAndHashCodeExample(“DBQ”, 25);

    val copyExample = new EqualsAndHashCodeExample(“DBQ”, 0);

    assertTrue(example.equals(copyExample));

}   

Note:

  1. Setting the callSuper attribute to true for classes that do not have any inheritance causes a compilation error.

  2. Final classes and classes that inherit from Object do not generate canEquals methods.

  3. The exclude attribute excludes certain fields from participating in the equals and hashCode overrides. The callSuper attribute specifies whether to call the equals and hashCode methods of the parent classes. The default value is false.

@noargsconstructor, @requiredargsconstructor, @allargsconstructor

Definition: Lombok automatically generates a no-argument constructor for annotated classes, specifying the argument constructor or all argument constructors.

Example:

@NoArgsConstructor(force = true)

@RequiredArgsConstructor(staticName = “create”)

@AllArgsConstructor(staticName = “of”)

public class ConstructorExample {

    private final String name;

    @NonNull 

    private int age;

    private char gender;

}

Unit tests:

@Test

public void testConstructorExample() {

    val noArgsExample = new ConstructorExample();

    val requiredArgsExample = ConstructorExample.create(“DBQ”, 25);

    val allArgsExample = ConstructorExample.of(“DBQ”, 20, ‘M’);

}

Note:

  1. @noargsconstructor automatically generates a no-argument constructor for the class. If the class contains final fields, a compilation error will occur. Initialize the final fields by specifying the property force to true.

  2. @requiredargsconstructor generates a constructor for the class that takes all final fields and fields annotated by @nonNULL.

  3. @allargsconstructor generates a full-parameter constructor for the class.

  4. All three annotations contain the staticName attribute, which is private to the constructor and exposes a static factory method that references the private constructor. The access attribute specifies access to the constructor, which is public by default.

9: @ Data

Definition: Bundle @toString, @equalSandHashCode, @getter / @setter, and @requiredargsConstructor annotations together and introduce them via @data.

Example:

@Data(staticConstructor = “of”)

public class DataExample {

    @NonNull

    private String name;

}

Unit tests:

@Test

public void testDataExample() {

    DataExample example = DataExample.of(“DBQ”);

    assertEquals(“DBQ”, example.getName());

    example.setName(“Code”);

    assertEquals(“Code”, example.getName());

    assertEquals(“DataExample(name=Code)”, example.toString());

}

Note:

  1. Some personalization properties of other annotations cannot be specified through @data and need to be displayed separately.

  2. The default generated Getter/Setter method access is public.

  3. All transient variables do not participate in the equals and hashCode methods.

  4. If a method of the same name has already been explicitly created in a class, Lombok does not generate it again.

  5. @data supports only staticConstructor, a private property that exposes static factory methods to create objects.

  6. You can tell Lombok to ignore explicitly added methods or constructors by adding an @tolerate annotation to a method or constructor to avoid Lombok detecting a problem where a method or constructor of the same name is not automatically generated.

Ten: @ the Value

Definition: Immutable variant implementation of the @data annotation

Note:

  1. @value final @toString @equalSandHashCode @allargsconstructor @fieldDefaults (makeFinal = true, Level = accesslevel.private) @getter all in one.

  2. The class itself and all fields in the class are of private final type and do not generate Setter methods.

  3. You can override default attributes by explicitly specifying an annotation.

  4. You can tell Lombok to ignore explicitly added methods or constructors by adding an @tolerate annotation to a method or constructor to avoid Lombok detecting a problem where a method or constructor of the same name is not automatically generated.

  5. Fields decorated with the @nonfinal annotation that are not final.

11: @ Builder

Definition: a pattern for creating objects by chain.

Example:

@Builder

@ToString

public class BuilderExample {

    @Builder.Default

    private String name = “DBQ”;

    private int age;

    @Singular

    private List<String> hobbies;

}

Unit tests:

@Test

public void testBuilderExample() {

    val hobbies = new ArrayList<String>();

    hobbies.add(“ping-pong”);

    hobbies.add(“baseball”);

    BuilderExample example = BuilderExample.builder()

            .age(20)

            .hobby(“basketball”)

            .hobby(“football”)

            .hobbies(hobbies)

            .build();

    assertEquals(

            “BuilderExample(name=DBQ, age=20, hobbies=[basketball, football, ping-pong, baseball])”

            , example.toString());

}

Note:

  1. Specify an initial value for the field via @Builder.default.

  2. Add the add method to the collection as well as the clear method by adding the @Singular annotation to the collection.

  3. You can personalize the class and method names you create with builderMethodName, buildMethodName, and buildClassName in the @Builder annotation.

Twelve: @ SneakyThrows

Definition: Converts checked exceptions to non-checked exceptions, avoiding throws or try statements.

Example:

public class SneakyThrowsExample { @SneakyThrows public void nlp() { throw new NullPointerException(); }}

Unit tests:

@Test

public void testSneakyThrowsExample() {

    new SneakyThrowsExample().nlp();

}

Note:

This feature is controversial and requires careful consideration when using it. Personally, I feel this feature is a chicken rib.

Thirteen: @ Synchronized

Definition: A variant of the synchronized modifier.

Example:

public class SynchronizedExample {

    private final Object readLock = new Object();

    @Synchronized

    public static void printName() {

        System.out.println(“DBQ”);

    }

    @Synchronized

    public int getAge() {

        return 25;

    }

    @Synchronized(“readLock”)

    public void sayHello() {

        System.out.println(“Hello Lombok!”);

    }

}

Note:

  1. Only for static or instance methods.

  2. Using @synchronized on static methods locks on Lombok’s generated field named $Lock, and instance methods Lock on Lombok’s generated field named $Lock.

  3. This field must exist when you explicitly name an annotation (such as readLock).

Fourteen: @ Getter (lazy = true)

Definition:

Example:

public class GetterLazyExample { @Getter(lazy=true) private final double[] cached = expensive(); private double[] expensive() { double[] result = new double[1000000]; for (int i = 0; i < result.length; i++) { result[i] = Math.asin(i); } return result; }}

Unit tests:

Note:

  1. Lazy loading applies to scenarios that occupy a large amount of CPU and memory and perform calculations only when data is really needed.

  2. Add lazy to @getter. As you can see from the figure above, the Example object just holds an empty AtomicReference and doesn’t actually evaluate until the actual getCached method is called, thus implementing what we call “lazy loading”.

  3. Variables must be private final.

For more information, see Lombok’s official website:

https://projectlombok.org/features/index.html

In my opinion, the source code is the best textbook, and Lombok’s annotations for each annotation are detailed and readily available.

This article introduces Lombok’s dozen or so annotations in terms of definitions, examples, and notes. As you can see, they can greatly reduce handwritten code duplication and keep code highly clean. Of course, every coin has two sides, and it also reduces code readability.