阿昌教你使用常用Lombok@注解

Posted 阿昌喜欢吃黄桃

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了阿昌教你使用常用Lombok@注解相关的知识,希望对你有一定的参考价值。

前言

老铁/老妹们好 (。・∀・)ノ゙!

今天阿昌分享的是常用的Lombok注解,官方地址github地址

做Java开发的,哪个不知道这小辣椒呢。Lombok是一个可以通过简单的注解形式来帮助我们简化消除一些必须有但显得很臃肿的Java代码的工具,提高开发人员的开发效率,通过使用对应的注解,可以在编译源码的时候生成对应的方法。


IDEA安装

  • 安装插件

  • 引入依赖
<!--lombok-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

常用注解

官方注解的介绍

1、@Data

@Data is a convenient shortcut annotation that bundles the features of @ToString, @EqualsAndHashCode, @Getter / @Setter and @RequiredArgsConstructor is a convenient shortcut annotation that bundles the features of @ToString, @EqualsAndHashCode, @Getter / @Setter and @RequiredArgsConstructor together

@Data注解在类上,会为类的所有属性自动生成setter/getter、equals、canEqual、hashCode、toString方法。

  • 注意点

    • 带有注解的参数(如callSuperincludeFieldNamesexclude)不能用 设置@Data
    • 所有生成的 getter 和 setter 都是public. 要覆盖访问级别,请使用显式@Setter和/或@Getter注释对字段或类进行注释
    • 所有标记为的字段transient都不会被考虑用于hashCodeequals
    • 所有静态字段都将被完全跳过(不考虑任何生成的方法,并且不会为它们制作 setter/getter)。
    • @Data(staticConstructor="of") class Foo<T> private T x;您可以Foo通过编写:Foo.of(5);而不是必须编写:来创建新实例new Foo<Integer>(5);
  • 使用Lombok

    @Data 
    public class DataExample 
        private final String name;
        @Setter(AccessLevel.PACKAGE) 
        private int age;
        private double score;
        private String[] tags;
    
        @ToString(includeFieldNames=true)
        @Data(staticConstructor="of")
        public static class Exercise<T> 
            private final String name;
            private final T value;
        
    
    
  • 不使用Lombok

public class DataExample 
    private final String name;
    private int age;
    private double score;
    private String[] tags;

    public DataExample(String name) 
        this.name = name;
    

    public String getName() 
        return this.name;
    

    void setAge(int age) 
        this.age = age;
    

    public int getAge() 
        return this.age;
    

    public void setScore(double score) 
        this.score = score;
    

    public double getScore() 
        return this.score;
    

    public String[] getTags() 
        return this.tags;
    

    public void setTags(String[] tags) 
        this.tags = tags;
    

    @Override public String toString() 
        return "DataExample(" + this.getName() + ", " + this.getAge() + ", " + this.getScore() + ", " + Arrays.deepToString(this.getTags()) + ")";
    

    protected boolean canEqual(Object other) 
        return other instanceof DataExample;
    

    @Override public boolean equals(Object o) 
        if (o == this) return true;
        if (!(o instanceof DataExample)) return false;
        DataExample other = (DataExample) o;
        if (!other.canEqual((Object)this)) return false;
        if (this.getName() == null ? other.getName() != null : !this.getName().equals(other.getName())) return false;
        if (this.getAge() != other.getAge()) return false;
        if (Double.compare(this.getScore(), other.getScore()) != 0) return false;
        if (!Arrays.deepEquals(this.getTags(), other.getTags())) return false;
        return true;
    

    @Override public int hashCode() 
        final int PRIME = 59;
        int result = 1;
        final long temp1 = Double.doubleToLongBits(this.getScore());
        result = (result*PRIME) + (this.getName() == null ? 43 : this.getName().hashCode());
        result = (result*PRIME) + this.getAge();
        result = (result*PRIME) + (int)(temp1 ^ (temp1 >>> 32));
        result = (result*PRIME) + Arrays.deepHashCode(this.getTags());
        return result;
    

    public static class Exercise<T> 
        private final String name;
        private final T value;

        private Exercise(String name, T value) 
            this.name = name;
            this.value = value;
        

        public static <T> Exercise<T> of(String name, T value) 
            return new Exercise<T>(name, value);
        

        public String getName() 
            return this.name;
        

        public T getValue() 
            return this.value;
        

        @Override public String toString() 
            return "Exercise(name=" + this.getName() + ", value=" + this.getValue() + ")";
        

        protected boolean canEqual(Object other) 
            return other instanceof Exercise;
        

        @Override public boolean equals(Object o) 
            if (o == this) return true;
            if (!(o instanceof Exercise)) return false;
            Exercise<?> other = (Exercise<?>) o;
            if (!other.canEqual((Object)this)) return false;
            if (this.getName() == null ? other.getValue() != null : !this.getName().equals(other.getName())) return false;
            if (this.getValue() == null ? other.getValue() != null : !this.getValue().equals(other.getValue())) return false;
            return true;
        

        @Override public int hashCode() 
            final int PRIME = 59;
            int result = 1;
            result = (result*PRIME) + (this.getName() == null ? 43 : this.getName().hashCode());
            result = (result*PRIME) + (this.getValue() == null ? 43 : this.getValue().hashCode());
            return result;
        
    
    


2、@Getter/@Setter

You can annotate any field with @Getter and/or @Setter, to let lombok generate the default getter/setter automatically.

使用@Getter和/或注释任何字段@Setter,让 lombok 自动生成默认的 getter/setter

  • 注意点
    • 默认 getter 仅返回该字段,并getFoo()在该字段被调用foo(或isFoo该字段的类型为boolean)时命名。
    • setFoo()如果该字段被调用foo、返回void并采用与该字段相同类型的 1 个参数,则会命名默认设置器。它只是将字段设置为此值。
    • 可以使用注解属性中AccessLevel.NONE来设置访问级别,为任何字段手动禁用 getter/setter 生成。
  • 使用Lombok
public class GetterSetterExample 
    @Getter @Setter 
    private int age = 10;

    @Setter(AccessLevel.PROTECTED) //生成set方法,并指定范围为protected
    private String name;

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

  • 不使用Lombok
public class GetterSetterExample 
    private int age = 10;
    private String name;
    @Override public String toString() 
        return String.format("%s (age: %d)", name, age);
    
    public int getAge() 
        return age;
    
    public void setAge(int age) 
        this.age = age;
    
    protected void setName(String name) 
        this.name = name;
    


3、@NonNull

You can use @NonNull on a record component, or a parameter of a method or constructor. This will cause to lombok generate a null-check statement for you.

@NonNull在记录组件、方法或构造函数的参数上使用。lombok 会为此生成一个空检查语句

  • 配置项

可选择指定,如果出错后抛出的异常是什么

lombok.nonNull.exceptionType= [ NullPointerException| IllegalArgumentException| JDK| Guava| Assertion]
#(默认值:)NullPointerException。
  • 使用Lombok
public class NonNullExample extends Something 
    private String name;

    public NonNullExample(@NonNull Person person) 
        super("Hello");
        this.name = person.getName();
    

  • 不使用Lombok
public class NonNullExample extends Something 
    private String name;
    public NonNullExample(@NonNull Person person) 
        super("Hello");
        if (person == null) 
            throw new NullPointerException("person is marked @NonNull but is null");
        
        this.name = person.getName();
    


4、@Cleanup

You can use @Cleanup to ensure a given resource is automatically cleaned up before the code execution path exits your current scope

@Cleanup可在代码执行路径退出当前范围之前自动清理给定资源

  • 注意点

    • @Cleanup InputStream in = new FileInputStream("some/file");
      //在所在范围的末尾,in.close()会被调用。
      
    • 如果您要清理的对象类型没有close()方法,但有其他一些无参数方法,则需要在注解属性中指定那个关闭方法,如:

      @Cleanup("dispose")
      
  • 使用Lombok

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

  • 不使用Lombok
public class CleanupExample 
    public static void main(String[] args) throws IOException 
        InputStream in = new FileInputStream(args[0]);
        try 
            OutputStream out = new FileOutputStream(args[1]);
            try 
                byte[] b = new byte[10000];
                while (true) 
                    int r = in.read(b);
                    if (r == -1) break;
                    out.write(b, 0, r);
                
             finally 
                if (out != null) 
                    out.close();
                
            
         finally 
            if (in != null) 
                in.close();
            
        
    


5、@EqualsAndHashCode

Any class definition may be annotated with @EqualsAndHashCode to let lombok generate implementations of the equals(Object other) and hashCode() methods

使用注释@EqualsAndHashCode来让 lombok 生成equals(Object other)hashCode()方法的实现

  • 注意点

    • 为类自动生成equalsandhashCode方法是一个不好的想法,因为其父类也可能定义了字段,这些字段也需要 equals/hashCode 代码,所以该类就不会生成方法。
    • 通过设置callSuper真正的,可以包括equalshashCode你的父类中生成的方法的方法。
  • 使用Lombok

@EqualsAndHashCode
public class EqualsAndHashCodeExample 
    private transient int transientVar = 10;
    private String name;
    private double score;
    //指定不为该属性,生成对应的EqualsAndHashCode
    @EqualsAndHashCode.Exclude private Shape shape = new Square(5, 10);
    private String[] tags;
    //指定不为该属性,生成对应的EqualsAndHashCode
    @EqualsAndHashCode.Exclude private int id;
    public String getName() 
        return this.name;
    
    
    //callSuper为父类也生成EqualsAndHashCode
    @EqualsAndHashCode(callSuper=true)
    public static class Square extends Shape 
        private final int width, height;

        public Square(int width, int height) 
            this.width = width;
            this.height = height;
        
    以上是关于阿昌教你使用常用Lombok@注解的主要内容,如果未能解决你的问题,请参考以下文章

阿昌教你自定义注解验证Bean对象

阿昌教你自定义注解验证Bean对象

lombok常用注解

lombok使用及常用注解

Java Lombok不常用注解

lombok中的@Builder.Default注解