Lombok基础使用

2020-06-25  本文已影响0人  我知他风雨兼程途径日暮不赏
  1. pom.xml依赖及IDEA插件安装
  2. 注解概要说明
  3. 注解详细说明

引言:Lombok需要安装专门的插件及maven依赖,实现原理也很简单,将.java按照lombok方式进行编译,自动解析对应的注解做出不同的动作,这里不再讨论实现细节,只是简单说明各个稳定版本的注解的使用

1. pom.xml依赖及IDEA插件安装

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

2.稳定版本注解概要说明

注解名称 注解作用域 注解说明
val 代替变量类型 自适应对应的变量类型,并将变量声明成final类型
var 代替变量类型 自适应对应变量类型,与val不同不会将变量声明成final类型
@NonNull 变量 判断该参数是否为null,如果是将抛出lombok异常
@Cleanup 变量 将自动资源管理,安全调用你的close()方法
@Getter/@Setter 变量、类 为类的全部字段或者变量生成getter/setter方法
@ToString 生成toString方法(toString的子注解有些是作用于字段,比如@ToString.Exclude)
@EqualsAndHashCode 生成equals()和hashcode()的方法
@NoArgsConstructor/@RequiredArgsConstructor/@AllArgsConstructor 生成无参构造方法,必填参数构造方法,及全参数构造方法
@Data @ToString、@EqualsAndHashCode、@Getter/@Setter和@RequiredArgsConstructor集合
@Value 不可变类的@Data注解
@Builder 生成建造者模式方法
@SneakyThrows 可用于不实际在方法的throws子句中声明而偷偷抛出已检查异常
@Getter(lazy=true) 字段 对字段内容赋予一次初值
@Log 代替繁杂的private static final Logger log = .....

3.注解详细说明

3.1 val

3.1.1 示例

通过val编写的java代码:

import java.util.ArrayList;
import java.util.HashMap;
import lombok.val;

public class ValExample {
  public String example() {
    val example = new ArrayList<String>();
    example.add("Hello, World!");
    val foo = example.get(0);
    return foo.toLowerCase();
  }
  
  public void example2() {
    val map = new HashMap<Integer, String>();
    map.put(0, "zero");
    map.put(5, "five");
    for (val entry : map.entrySet()) {
      System.out.printf("%d: %s\n", entry.getKey(), entry.getValue());
    }
  }
}

编译结果:


import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class ValExample {
  public String example() {
    final ArrayList<String> example = new ArrayList<String>();
    example.add("Hello, World!");
    final String foo = example.get(0);
    return foo.toLowerCase();
  }
  
  public void example2() {
    final HashMap<Integer, String> map = new HashMap<Integer, String>();
    map.put(0, "zero");
    map.put(5, "five");
    for (final Map.Entry<Integer, String> entry : map.entrySet()) {
      System.out.printf("%d: %s\n", entry.getKey(), entry.getValue());
    }
  }
}

需要注意的是:这个特性在NetbBeans中不支持。
其实我自己编译的时候,并没有final关键字和var效果一致。。。

3.1.2 支持配置

lombok.val.flagUsage = [warning|error](默认为不设置)
如果配置上了val会被标记为(warning|error)

3.1.3 附属详细说明

3.2 var

3.2.1 示例

和3.1.1一样,不再复述。

3.2.2 支持配置

lombok.var.flagUsage = [warning|error](默认为不设置)
如果配置上了var会被标记为(warning|error)

3.2.3 附属详细说明

3.3 @NonNull

3.3.1 示例

package study.lombok;

import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;

/**
 * @Author LynHB
 * @Description : Lombok @NonNull注解测试
 * @Date 20:23 2020/6/24
 **/
public class NonNullAnnotation {

    @Getter
    @Setter
    public class Person{
        private String name;
        private int age;
    }

    public void testPersonIsNull(@NonNull Person person){
        System.out.println(person.getName());
    }

    public static void  main(String[] args){
        NonNullAnnotation nonNullAnnotation = new NonNullAnnotation();
        nonNullAnnotation.testPersonIsNull(null);
    }
}

编译结果1:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package study.lombok;

import lombok.NonNull;

public class NonNullAnnotation {
    public NonNullAnnotation() {
    }

    public void testPersonIsNull(@NonNull NonNullAnnotation.Person person) {
        if (person == null) {
            throw new NullPointerException("person is marked non-null but is null");
        } else {
            System.out.println(person.getName());
        }
    }

    public static void main(String[] args) {
        NonNullAnnotation nonNullAnnotation = new NonNullAnnotation();
        nonNullAnnotation.testPersonIsNull((NonNullAnnotation.Person)null);
    }

    public class Person {
        private String name;
        private int age;

        public Person() {
        }

        public String getName() {
            return this.name;
        }

        public int getAge() {
            return this.age;
        }

        public void setName(String name) {
            this.name = name;
        }

        public void setAge(int age) {
            this.age = age;
        }
    }
}

代码片段2:

package study.lombok;

import lombok.Data;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;

/**
 * @Author LynHB
 * @Description : Lombok @NonNull注解测试
 * @Date 20:23 2020/6/24
 **/
public class NonNullAnnotation {

    @Getter
    @Setter
    @Data
    public static class Person{
        @NonNull private String name;
        private int age;
    }

    public void testPersonIsNull(Person person){
        System.out.println(person.getName());
    }

    public static void  main(String[] args){
        NonNullAnnotation nonNullAnnotation = new NonNullAnnotation();
        Person person = new Person(null);
        nonNullAnnotation.testPersonIsNull(person);
    }
}

编译结果2:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package study.lombok;

import lombok.NonNull;

public class NonNullAnnotation {
    public NonNullAnnotation() {
    }

    public void testPersonIsNull(NonNullAnnotation.Person person) {
        System.out.println(person.getName());
    }

    public static void main(String[] args) {
        NonNullAnnotation nonNullAnnotation = new NonNullAnnotation();
        NonNullAnnotation.Person person = new NonNullAnnotation.Person((String)null);
        nonNullAnnotation.testPersonIsNull(person);
    }

    public static class Person {
        @NonNull
        private String name;
        private int age;

        @NonNull
        public String getName() {
            return this.name;
        }

        public int getAge() {
            return this.age;
        }

        public void setName(@NonNull String name) {
            if (name == null) {
                throw new NullPointerException("name is marked non-null but is null");
            } else {
                this.name = name;
            }
        }

        public void setAge(int age) {
            this.age = age;
        }

        public Person(@NonNull String name) {
            if (name == null) {
                throw new NullPointerException("name is marked non-null but is null");
            } else {
                this.name = name;
            }
        }

        public boolean equals(Object o) {
            if (o == this) {
                return true;
            } else if (!(o instanceof NonNullAnnotation.Person)) {
                return false;
            } else {
                NonNullAnnotation.Person other = (NonNullAnnotation.Person)o;
                if (!other.canEqual(this)) {
                    return false;
                } else {
                    Object this$name = this.getName();
                    Object other$name = other.getName();
                    if (this$name == null) {
                        if (other$name == null) {
                            return this.getAge() == other.getAge();
                        }
                    } else if (this$name.equals(other$name)) {
                        return this.getAge() == other.getAge();
                    }

                    return false;
                }
            }
        }

        protected boolean canEqual(Object other) {
            return other instanceof NonNullAnnotation.Person;
        }

        public int hashCode() {
            int PRIME = true;
            int result = 1;
            Object $name = this.getName();
            int result = result * 59 + ($name == null ? 43 : $name.hashCode());
            result = result * 59 + this.getAge();
            return result;
        }

        public String toString() {
            return "NonNullAnnotation.Person(name=" + this.getName() + ", age=" + this.getAge() + ")";
        }
    }
}

3.3.2 支持配置

3.4 @Cleanup

3.4.1 示例

代码片段:

package study.lombok;

import lombok.Cleanup;

import java.io.*;

/**
 * @Author LynHB
 * @Description :
 * @Date 21:03 2020/6/24
 **/
public class CleanupExample {
    public static void main(String[] args) throws IOException {
        @Cleanup InputStream in = new FileInputStream(args[0]);
        @Cleanup OutputStream out = new FileOutputStream(args[1]);
        byte[] b = new byte[10000];
        while (true) {
            int r = in.read(b);
            if (r == -1) break;
            out.write(b, 0, r);
        }
    }
}

编译结果:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package study.lombok;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collections;

public class CleanupExample {
    public CleanupExample() {
    }

    public static void main(String[] args) throws IOException {
        FileInputStream in = new FileInputStream(args[0]);

        try {
            FileOutputStream out = new FileOutputStream(args[1]);

            try {
                byte[] b = new byte[10000];

                while(true) {
                    int r = in.read(b);
                    if (r == -1) {
                        return;
                    }

                    out.write(b, 0, r);
                }
            } finally {
                if (Collections.singletonList(out).get(0) != null) {
                    out.close();
                }

            }
        } finally {
            if (Collections.singletonList(in).get(0) != null) {
                in.close();
            }

        }
    }
}

3.4.2 支持配置

3.5 @Getter/@Setter

3.5.1 示例

package study.lombok;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;

/**
 * @Author LynHB
 * @Description : Getting Setting方法demo
 * @Date 22:48 2020/6/24
 **/
public class GetterSetterExample {
    @Getter
    @Setter
    private int age = 10;
    @Setter(AccessLevel.PROTECTED) private String name;

    @Override public String toString() {
        return String.format("%s (age: %d)", name, age);
    }
}

编译结果:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package study.lombok;

public class GetterSetterExample {
    private int age = 10;
    private String name;

    public GetterSetterExample() {
    }

    public String toString() {
        return String.format("%s (age: %d)", this.name, this.age);
    }

    public int getAge() {
        return this.age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    protected void setName(String name) {
        this.name = name;
    }
}

3.5.2 支持配置

配置项 可选值 默认值 配置说明
lombok.accessors.chain true false false 如果设置为true,会返回this(代替viod)。显式的配置@Accessors注解chain会优先于此设置。
lombok.accessors.fluent true false false 如果设置为true,不会生成'get' 'is' 'set'前缀,相反的是方法会用自身的字段名称作为函数名。显式的配置@Accessors注解fluent会优先于此设置。
lombok.accessors.prefix +=自定义前缀字符串 空列表 这是一个列表属性;可以通过+=进行添加。继承父配置文件中的删除-=操作。Lombok将从字段名称中删除任何匹配的字段前缀,以便确定要生成的getter/setter的名称。例如,如果m是这个设置中列出的前缀之一,那么一个名为mFoobar的字段将导致一个名为getFoobar()的getter,而不是getMFoobar()。显式的配置@Accessors注解prefix会优先于此设置。
lombok.getter.noIsPrefix true false false 如果设置为true,为boolean类型设置get前缀而非is前缀,所有生成的代码有调用到getters的地方,比如@ToString也会用get而不是is。
lombok.setter.flagUsage warning error 不设置 同其他注解
lombok.getter.flagUsage warning eroor 不设置 同其他注解
lombok.copyableAnnotations 完全限定类型列表 空集合 lombok将会拷贝这些注解从字段复制到setter参数和getter方法。注意lombok附带了一些开箱的注解,这些注解都可以复制,所有流行的可空/非空注解。

3.6 @ToString

3.6.1 示例

代码片段:

package study.lombok;

import lombok.ToString;

import java.awt.*;

/**
 * @Author LynHB
 * @Description : ToString注解测试
 * @Date 13:26 2020/6/25
 **/
@ToString
public class ToStringExample {
    private static final int STATIC_VAR = 10;
    private String name;
    private Shape shape = new Square(5, 10);
    private String[] tags;
    @ToString.Exclude private int id;

    public String getName() {
        return this.name;
    }

    public static class Shape{

    }

    @ToString(callSuper=true, includeFieldNames=true)
    public static class Square extends Shape {
        private final int width, height;

        public Square(int width, int height) {
            this.width = width;
            this.height = height;
        }
    }
}

编译结果:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package study.lombok;

import java.util.Arrays;

public class ToStringExample {
    private static final int STATIC_VAR = 10;
    private String name;
    private ToStringExample.Shape shape = new ToStringExample.Square(5, 10);
    private String[] tags;
    private int id;

    public ToStringExample() {
    }

    public String getName() {
        return this.name;
    }

    public String toString() {
        return "ToStringExample(name=" + this.getName() + ", shape=" + this.shape + ", tags=" + Arrays.deepToString(this.tags) + ")";
    }

    public static class Square extends ToStringExample.Shape {
        private final int width;
        private final int height;

        public Square(int width, int height) {
            this.width = width;
            this.height = height;
        }

        public String toString() {
            return "ToStringExample.Square(super=" + super.toString() + ", width=" + this.width + ", height=" + this.height + ")";
        }
    }

    public static class Shape {
        public Shape() {
        }
    }
}

3.6.2 支持配置

配置项 可选值 默认值 配置说明
lombok.toString.includeFieldNames true false true 通常,lombok以fieldName = fieldValue的形式为每个字段生成toString响应的片段。如果设置成false,lombok将会省略名称字段,只部署一个逗号分隔的所有字段值列表。注解参数“includeFieldNames”,如果明确的指定,优先于此配置。
lombok.toString.doNotUseGetters true false false 如果设置成true,lombok将会直接访问字段,跳过getters当生产生产toString方法时。这个注解参数“doNotUseGetters”,如果明确指定,则优先于此配置
lombok.toString.callSuper call skip warn skip 如果设置成call,lombok将会调用父类实现的toString当你的类继承父类时。如果设置成skip,不会这调用。如果设置成warn,也没有生成这样的调用,但是lombok会生成一个警告来告诉你。
lombok.toString.flagUsage warning error 不设置 同其他注解

3.7 @EqualsAndHashCode

3.7.1 示例

3.7.2 支持配置

配置项 可选值 默认值 配置说明

3.8 @NoArgsConstructor/@RequiredArgsConstructor/@AllArgsConstructor

3.8.1 示例

3.8.2 支持配置

配置项 可选值 默认值 配置说明

3.9 @Data

3.9.1 示例

3.9.2 支持配置

配置项 可选值 默认值 配置说明

3.10 @Value

3.10.1 示例

3.10.2 支持配置

配置项 可选值 默认值 配置说明

3.11 @Builder

3.11.1 示例

3.11.2 支持配置

配置项 可选值 默认值 配置说明

3.12 @SneakyThrows

3.12.1 示例

3.12.2 支持配置

配置项 可选值 默认值 配置说明

3.13 @Getter(lazy=true)

3.13.1 示例

3.13.2 支持配置

配置项 可选值 默认值 配置说明

3.14 @Log

你可以使用变量@Log在你的class中(保证对应的logging是你有用的,说白了就是你的依赖中要有它);之前的做法是你需要定义一个static final log的字段,初始化它各种巴拉巴拉的语句,现在只需要对应的@Log注解即可实现:

@CommonsLog
// 被翻译成如下
private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(LogExample.class);
@Flogger
// 被翻译成如下
private static final com.google.common.flogger.FluentLogger log = com.google.common.flogger.FluentLogger.forEnclosingClass();
@JBossLog
// 被翻译成如下
private static final org.jboss.logging.Logger log = org.jboss.logging.Logger.getLogger(LogExample.class);
@Log
// 被翻译成如下
private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName());
@Log4j
// 被翻译成如下
private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LogExample.class);
@Log4j2
// 被翻译成如下
private static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger(LogExample.class);
@Slf4j
// 被翻译成如下
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class);
@XSlf4j
// 被翻译成如下
private static final org.slf4j.ext.XLogger log = org.slf4j.ext.XLoggerFactory.getXLogger(LogExample.class);
@CustomLog
// 被翻译成如下
private static final com.foo.your.Logger log = com.foo.your.LoggerFactory.createYourLogger(LogExample.class);

3.14.1 示例

package study.dynamic.proxy.entity;


import lombok.extern.slf4j.Slf4j;

/**
 * @Author LynHB
 * @Description :
 *      Baby 实现来自IPerson接口的类
 * @Date 23:17 2020/7/8
 **/
@Slf4j
public class Baby implements IPerson {
    @Override
    public void eat(String dishName) {
        log.info("mother feed me {}",dishName);
    }

    @Override
    public void hungry() {
        log.info("wa wa wa");
    }
}

3.14.2 支持配置

配置项 可选值 默认值 配置说明
上一篇下一篇

猜你喜欢

热点阅读