Ten minutes to get to know and use the principle of Lombok

1 Introduction

Lombok is an easy to use handy tools, like Google Guava like this to be highly recommended, every Java engineers should use it. Lombok is a Java ™ utility that can be used to help Java developers to eliminate lengthy codes, especially for simple Java objects (POJO). It does this by a comment . Lombok achieved by the development environment, developers can save build such hashCode () and equals () methods, and such a lot of time conventionally used to classify a variety of accessor and mutator.

2 IntelliJ installation Lombok

  1. IntelliJ plug-ins installed by center

    img

  2. Install Plugin

    img

  3. Finally, it should be noted that, when using lombok annotation remember to import lombok.jar package to the project, if you are using Maven Project, to add dependencies in pom.xml.

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

3 Lombok Usage

3.1 Lombok explanatory notes

  • val: Used in front of a local variable, corresponding to the variable declared as final

  • @NonNull: To increase this annotation method parameters will automatically check whether it is empty of the parameters in the method, if it is empty, then throws NPE (NullPointerException)

  • @Cleanup: Automatic management of resources, local variables used before, is about to execute within the current range of variables will automatically clean up resources before you get out, automatically generate code like this try-finally close the stream

  • @Getter/@Setter: Use on the property, no longer have their own handwriting setter and getter methods, you can also specify the scope of access

  • @ToString: Used in class, you can automatically override toString method, of course, other parameters may also be added, e.g. @ToString (exclude = "id") to exclude id attribute, or @ToString (callSuper = true, includeFieldNames = true) call the parent class toString method, comprising all the properties

  • @EqualsAndHashCode: Based on use, automatically generating equals and hashCode methods

  • @NoArgsConstructor, @RequiredArgsConstructor and @AllArgsConstructor: With class, automatically generated constructor with no arguments constructor and use all parameters and all @NonNull properties as a constructor parameter, if specified staticName = "of" parameters, and returns the class object also generates a static factory method, a lot easier than using the constructor

  • @Data: Notes on the class, is equivalent to giving @ToString, @EqualsAndHashCode, @Getter, @Setterand @RequiredArgsConstrutorthese notes, to POJO类be useful

  • @Value: With class is immutable in the form of @Data, is equivalent to adding attributes declared final, only provides getter methods, without providing setter methods

  • @Builder: For use in class, constructor, method on providing complex builder APIs for you, you can make the same call as follows Person.builder().name("Adam Savage").city("San Francisco").job("Mythbusters").job("Unchained Reaction").build();more instructions refer Builder

  • @SneakyThrows: Auto subjects throw an exception, without the explicit statement in the method throws

  • @Synchronized: Used in the method, the method is declared as synchronized, and automatically lock, and lock the object is a private property $lockor $LOCKwhile java in synchronized keyword lock object is this, latched on this or your own class objects the side effect that you can not stop uncontrolled code to lock this class or object, which may result in race conditions or other threading errors

  • @Getter(lazy=true): You can replace the classic Double Check Lock boilerplate code

  • @Log

    : Generation of different types depending on the annotation log object, but the instance names are log, there are six alternative implementation class

    • @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);

Code Example 3.2 Lombok

  1. val example
public static void main(String[] args) {
    val sets = new HashSet<String>();
    val lists = new ArrayList<String>();
    val maps = new HashMap<String, String>();
    //=>相当于如下
    final Set<String> sets2 = new HashSet<>();
    final List<String> lists2 = new ArrayList<>();
    final Map<String, String> maps2 = new HashMap<>();
}
  1. @NonNull example
public void notNullExample(@NonNull String string) {
    string.length();
}
//=>相当于
public void notNullExample(String string) {
    if (string != null) {
        string.length();
    } else {
        throw new NullPointerException("null");
    }
}
  1. @Cleanup example
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();
            }
        }
    }
}
  1. @ Getter / @ Setter example
@Setter(AccessLevel.PUBLIC)
@Getter(AccessLevel.PROTECTED)
private int id;
private String shap;
  1. @ToString example
@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());
    }
}
  1. @EqualsAndHashCode example
@EqualsAndHashCode(exclude = {"id", "shape"}, callSuper = false)
public class LombokDemo {
    private int id;
    private String shap;
}
  1. @NoArgsConstructor, @RequiredArgsConstructor and @AllArgsConstructor示例
@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");
        //使用静态工厂方法
        LombokDemo.of(2, "circle");
        //无参构造
        new LombokDemo();
        //包含所有参数
        new LombokDemo(1, "circle", 2);
    }
}
  1. @Data example
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;
}
  1. @Value example
@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;
    }
    ...
}
  1. @Builder example
@Builder
public class BuilderExample {
    private String name;
    private int age;
    @Singular
    private Set<String> occupations;
    public static void main(String[] args) {
        BuilderExample test = BuilderExample.builder().age(11).name("test").build();
    }
}
  1. @SneakyThrows example
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();
    }
}
  1. Examples @Synchronized
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");
        }
    }
}
  1. @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;
    }
}

// 相当于如下所示: 

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

Principle 4 Lombok comment

Said Lombok, we have to mention 269 JSR: Pluggable Annotation Processing API ( www.jcp.org/en/jsr/deta... ). Before JSR 269 we also have this artifact annotations, but we want to do such reflection must be used, the method reflected greater limitations. First, it must be defined as @Retention RetentionPolicy.RUNTIME, only annotations acquired by reflection values at runtime, so as to reduce the efficiency of the code is running . Secondly, if you want to use annotations at compile some checking, error reporting gives users the code of some unreasonable, usage reflected on the powerless. And then we can use the JSR 269 annotations do these things at compile the Javac . So we find the core of the distinction is in the run or compile .

img

Seen from the figure, Annotation Processing is a step between the parsing and generation. DETAILED detailed steps are as follows:

img

The figure is a process flow Lombok, after parsing into an abstract syntax tree in Javac (AST), Lombok annotation processor according to their dynamic changes AST, adding a new node (the so-called Code), and finally by analyzing the generated bytecode .

Since Java 6 onwards, javac to support "JSR 269 Pluggable Annotation Processing API" specifications, as long as the program implements the API, you can get called when running javac .

  1. Third-party tools commonly used Maven project management tool used by the java compiler tool from the configuration, if we configure the third-party tools for Oracle javac, then Maven will directly support the lombok;
  2. Intellij Idea configuration tools for Oracle javac compiler, then, will directly support the lombok;

IDE tool to solve the problem:

Now there is a class A, which has some of the fields, did not create them setter and getter methods, use of lombok @Data annotations, and another type one, B, it calls the corresponding field A setter and getter methods class instances

Compiling program categories A and B are located, and will not be given, because the setter and getter methods exist corresponding field A final class bytecode files generated

However, IDE found Class A Class B instance source code used in the setter and getter methods defined in the class A can not find the source code, IDE will think this is an error

To resolve the above error is not really wrong, you can download and install Intellij Idea of ​​"Lombok plugin".

5 custom support JSR269 annotations

General javac compilation process, java file first constructed by analyzing an AST, and then perform the annotation process, and finally through the analysis and optimization to generate binary .class files. We can do is to adjust some process in the annotation processing stage . First, we create the following files in the META-INF.services:

img

File specified in our annotation processor: com.alipay.kris.other.lombok.MyAnnotaionProcessor , then we can then write your own annotation 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
    }
}

Guess you like

Origin www.cnblogs.com/alterem/p/11409308.html