preface

Lombok is a handy tool that, like Google Guava, is highly recommended and should be used by every Java engineer. Lombok is a Java™ utility that helps developers eliminate Java’s verbose code, especially for simple Java objects (POJOs). It does this through annotations. By implementing Lombok in a development environment, developers can save a lot of time building methods like hashCode() and equals() and sorting various accessors and mutators.

IntelliJ installs Lombok

  1. Install via IntelliJ’s plug-in center

  2. Install Plugin

  3. Finally, remember to import lombok. Jar into your Project when using Lombok annotations, and add dependencies to pom.xml if you are using Maven Project.

    Org. Projectlombok lombok 1.16.8

Lombok

2.1 Lombok notes

  • val: used before a local variable, which is equivalent to declaring the variable final
  • @NonNullAdding this annotation to a method parameter automatically verifies whether the parameter is null within the method. If it is null, NullPointerException (NPE) is thrown.
  • @Cleanup: Automatically manages resources before local variables, cleans up resources before exiting within the current variable scope, and automatically generates try-finally code to close the stream
  • @Getter/@Setter: for properties, you no longer have to write your own setters and getters, and you can also specify access scopes
  • @ToString: ToString(exclude= “id”); toString (exclude= “id”); toString (exclude= “id”) Or @toString (callSuper=true, includeFieldNames=true) calls the ToString method of the parent class, containing all attributes
  • @EqualsAndHashCodeThe equals method and hashCode method are automatically generated for the class
  • @NoArgsConstructor, @RequiredArgsConstructor and @AllArgsConstructorFor classes, it automatically generates no-argument constructors that take all arguments and constructors that take all @nonNULL attributes as arguments. Specifying staticName = “of” also generates a static factory method that returns the class object, which is much more convenient than using the constructor
  • @DataAnnotations are used simultaneously on the class@ToString,@EqualsAndHashCode,@Getter,@Setterand@RequiredArgsConstrutorThese notes, forPOJO classIt is useful to
  • @ValueUsed in classes, the immutable form of @data is equivalent to adding a final declaration to a property, providing getter methods instead of setter methods
  • @BuilderFor classes, constructors, and methods, it provides you with the complex Builder APIs that you can call as followsPerson.builder().name("Adam Savage").city("San Francisco").job("Mythbusters").job("Unchained Reaction").build();For more informationBuilder
  • @SneakyThrows: Automatically throws checked exceptions without explicitly using throws statements on methods
  • @Synchronized: used on a method to declare the method synchronous and automatically lock the lock object, which is a private property$lockor$LOCKLocking on this or its own class has the side effect that you cannot prevent uncontrolled code from locking this or its own class, which can cause race conditions or other thread errors
  • @Getter(lazy=true): can replace the classic Double Check Lock boilerplate code
  • @Log: Generates different types of log objects based on different annotations, but the instance name is log, and there are six optional implementation classes
    • @CommonsLog Creates log = org.apache.commons.logging.LogFactory.getLog(LogExample.class);
    • @Log Creates log = java.util.logging.Logger.getLogger(LogExample.class.getName());
    • @Log4j Creates log = org.apache.log4j.Logger.getLogger(LogExample.class);
    • @Log4j2 Creates log = org.apache.logging.log4j.LogManager.getLogger(LogExample.class);
    • @Slf4j Creates log = org.slf4j.LoggerFactory.getLogger(LogExample.class);
    • @XSlf4j Creates log = org.slf4j.ext.XLoggerFactory.getXLogger(LogExample.class);

2.2 Lombok code examples

  1. Val sample

    public static void main(String[] args) { val sets = new HashSet(); val lists = new ArrayList(); val maps = new HashMap<String, String>(); Final Set sets2 = new HashSet<>(); final List lists2 = new ArrayList<>(); final Map<String, String> maps2 = new HashMap<>(); }

  2. @ NonNull sample

    public void notNullExample(@NonNull String string) { string.length(); } public void notNullExample(String String) {if (String! = null) { string.length(); } else { throw new NullPointerException(“null”); }}

  3. @ the Cleanup examples

    public static void main(String[] args) { try { @Cleanup InputStream inputStream = new FileInputStream(args[0]); } catch (FileNotFoundException e) { e.printStackTrace(); } InputStream InputStream = null; try { inputStream = new FileInputStream(args[0]); } catch (FileNotFoundException e) { e.printStackTrace(); } finally { if (inputStream ! = null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); }}}}

  4. @ Getter / @ Setter example

    @Setter(AccessLevel.PUBLIC) @Getter(AccessLevel.PROTECTED) private int id; private String shap;

  5. @ ToString sample

    @ToString(exclude = “id”, callSuper = true, includeFieldNames = true) public class LombokDemo { private int id; private String name; private int age; Public static void main(String[] args) {LombokDemo(super=LombokDemo@48524010, name=null, age=0) System.out.println(new LombokDemo()); }}

  6. @ EqualsAndHashCode sample

    @EqualsAndHashCode(exclude = {“id”, “shape”}, callSuper = false) public class LombokDemo { private int id; private String shap; }

  7. NoArgsConstructor, @requiredargsconstructor and @allargsconstructor examples

    @NoArgsConstructor @RequiredArgsConstructor(staticName = “of”) @AllArgsConstructor public class LombokDemo { @NonNull private int id; @NonNull private String shap; private int age; public static void main(String[] args) { new LombokDemo(1, “circle”); // Use the static factory method lombokdemo. of(2, “circle”); // Construct new LombokDemo() with no arguments; New LombokDemo(1, “circle”, 2); }}

  8. @ the Data sample

    import lombok.Data; @Data public class Menu { private String shopId; private String skuMenuId; private String skuName; private String normalizeSkuName; private String dishMenuId; private String dishName; private String dishNum; //默认阈值 private float thresHold = 0; //新阈值 private float newThresHold = 0; //总得分 private float totalScore = 0; }

  9. @ the Value sample

    @Value public class LombokDemo { @NonNull private int id; @NonNull private String shap; private int age; Private final int id; public int getId() { return this.id; }… }

  10. @ Builder sample

    @Builder public class BuilderExample { private String name; private int age; @Singular private Set occupations; public static void main(String[] args) { BuilderExample test = BuilderExample.builder().age(11).name(“test”).build(); }}

  11. @ SneakyThrows sample

    import lombok.SneakyThrows; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.io.UnsupportedEncodingException; public class Test { @SneakyThrows() public void read() { InputStream inputStream = new FileInputStream(“”); } @SneakyThrows public void write() { throw new UnsupportedEncodingException(); Public void read() throws FileNotFoundException {InputStream InputStream = new FileInputStream(“”); } public void write() throws UnsupportedEncodingException { throw new UnsupportedEncodingException(); }}

  12. @ Synchronized sample

    public class SynchronizedDemo { @Synchronized public static void hello() { System.out.println(“world”); } private static final Object LOCK = new Object[0]; public static void hello() { synchronized (LOCK) { System.out.println(“world”); }}}

  13. @Getter(lazy = true)

    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; }}

    // Equivalent to the following:

    import java.util.concurrent.atomic.AtomicReference; public class GetterLazyExample { private final AtomicReference<java.lang.Object> cached = new AtomicReference<>(); public double[] getCached() { java.lang.Object value = this.cached.get(); if (value == null) { synchronized (this.cached) { value = this.cached.get(); if (value == null) { final double[] actualValue = expensive(); value = actualValue == null ? this.cached : actualValue; this.cached.set(value); } } } return (double[]) (value == this.cached ? null : value); } private double[] expensive() { double[] result = new double[1000000]; for (int i = 0; i < result.length; i++) { result[i] = Math.asin(i); } return result; }}

Lombok annotations

Speaking of Lombok, we have to mention JSR 269: Pluggable Annotation Processing API. We had annotations before JSR 269, but we had to use reflection to do something, and reflection was very limited. First, it must define @retention as retentionpolicy.runtime, which can only get annotation values at RUNTIME through reflection, making run-time code inefficient. Second, if you want to use annotations to do some checking at compile time, and to report errors to the user for some unreasonable code, reflection doesn’t work. After JSR 269 we can use annotations to do this at compile time in Javac. So we find that the core differentiates between run time and compile time.

As you can see from the figure above, Annotation Processing is a step between parsing and generation. The detailed steps are as follows:

The diagram above shows Lombok’s process. After the Javac has been parsed into an abstract syntax tree (AST), Lombok dynamically modiates the AST, adding new nodes (called code), and eventually parsing and generating bytecode, based on its own annotation processor.

Since Java 6, Javac has supported the “JSR 269 Pluggable Annotation Processing API” specification, which can be called whenever a program implements the API while Javac is running.

  1. The Java compiler used by Maven, a popular project management tool, is configured with a third-party tool. If you configure the third-party tool as Oracle Javac, then Maven supports Lombok directly.
  2. If Intellij Idea is configured using Oracle Javac, lombok is directly supported.

IDE tool problem solving:

You now have A class A with some fields that use Lombok’s @data annotation without the setter and getter methods for creating them, and A class B that calls the setter and getter methods for the corresponding fields of class A instances

Compiling projects in class A and class B does not generate an error because the resulting class A bytecode file has setter and getter methods for the corresponding fields

However, the IDE finds that setter and getter methods for class A instances used in class B source code are not defined in class A source code, and the IDE considers this an error

To resolve the above error, which is not a true error, download and install the “Lombok Plugin “in Intellij Idea.

4. Customize annotations to support JSR269

In the general compilation process of JavAC, Java files are first parsed to build an AST, followed by annotation processing, and finally analyzed and optimized to generate binary.class files. What we can do is do some processing in the annotation processing phase. First we create the following files under meta-inf. services:

Documents specified in the annotation processor: com. Alipay. Kris. Other. Lombok. MyAnnotaionProcessor, then we meet you can write your own annotations processor, a simple example code is as follows:

@SupportedSourceVersion(SourceVersion.RELEASE_8)
@SupportedAnnotationTypes("com.alipay.kris.other.lombok.*")
public class MyAnnotaionProcessor extends AbstractProcessor {
    public MyAnnotaionProcessor() {
        super();
    }
    @Override
    public boolean process(Set<? extends TypeElement> annotations,RoundEnvironment roundEnv) {
        for (Element elem : roundEnv.getElementsAnnotatedWith(MyAnnotation.class)) {
            MyAnnotation annotation = elem.getAnnotation(MyAnnotation.class);
            String message = "annotation found in " + elem.getSimpleName()
                + " with  " + annotation.value();
            addToString(elem);
            processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, message);
        }
        return true; // no further processing of this annotation type
    }
}
Copy the code

That’s the end of the article

Like xiaobian to share technical articles can like attention oh!

There are also some Java core information collection and 2020Java interview information summary

Public account: Kylin bug