lombok使用简介

原文地址: http://www.jianshu.com/p/365ea41b3573

Lombok简介

Lombok是一个可以通过简单的注解形式来帮助我们简化消除一些必须有但显得很臃肿的Java代码的工具,通过使用对应的注解,可以在编译源码的时候生成对应的方法。官方地址:https://projectlombok.org/,github地址:https://github.com/rzwitserloot/lombok。

IntelliJ IDEA 使用它的方法

  • 先安装插件


    Paste_Image.png

  • 然后引入lombok的jar包
    <dependency> 
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.16.14</version>
    </dependency>

注解的介绍

官方注解介绍

  • @Getter and @Setter

    你可以用@Getter / @Setter注释任何字段,让lombok自动生成默认的getter / setter方法。
    默认生成的方法是public的,如果要修改方法修饰符可以设置AccessLevel的值,例如:@Getter(access = AccessLevel.PROTECTED)


    Paste_Image.png
    import lombok.AccessLevel;
    import lombok.Getter;
    import lombok.Setter;
    public class User {
     @Getter(AccessLevel.PROTECTED) @Setter private Integer id;
     @Getter @Setter private String name;
     @Getter @Setter private String phone;
    }
  • @ToString

    生成toString()方法,默认情况下,它会按顺序(以逗号分隔)打印你的类名称以及每个字段。可以这样设置不包含哪些字段@ToString(exclude = “id”) / @ToString(exclude = {“id”,”name”})
    如果继承的有父类的话,可以设置callSuper 让其调用父类的toString()方法,例如:@ToString(callSuper = true)

    import lombok.ToString;
    @ToString(exclude = {"id","name"})
    public class User {
     private Integer id;
     private String name;
     private String phone;
    }

    生成toString方法如下:

    public String toString(){
     return "User(phone=" + phone + ")";
    }
  • @EqualsAndHashCode

    生成hashCode()和equals()方法,默认情况下,它将使用所有非静态,非transient字段。但可以通过在可选的exclude参数中来排除更多字段。或者,通过在parameter参数中命名它们来准确指定希望使用哪些字段。

    @EqualsAndHashCode(exclude={"id", "shape"})
    public class EqualsAndHashCodeExample {
     private transient int transientVar = 10;
     private String name;
     private double score;
     private Shape shape = new Square(5, 10);
     private String[] tags;
     private transient int id;
    
     public String getName() {
       return this.name;
     }
    
     @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;
       }
     }
    }

    对比代码如下:

    import java.util.Arrays;
    public class EqualsAndHashCodeExample {
     private transient int transientVar = 10;
     private String name;
     private double score;
     private Shape shape = new Square(5, 10);
     private String[] tags;
     private transient int id;
    
     public String getName() {
       return this.name;
     }
    
     @Override public boolean equals(Object o) {
       if (o == this) return true;
       if (!(o instanceof EqualsAndHashCodeExample)) return false;
       EqualsAndHashCodeExample other = (EqualsAndHashCodeExample) o;
       if (!other.canEqual((Object)this)) return false;
       if (this.getName() == null ? other.getName() != null : !this.getName().equals(other.getName())) return false;
       if (Double.compare(this.score, other.score) != 0) return false;
       if (!Arrays.deepEquals(this.tags, other.tags)) return false;
       return true;
     }
    
     @Override public int hashCode() {
       final int PRIME = 59;
       int result = 1;
       final long temp1 = Double.doubleToLongBits(this.score);
       result = (result*PRIME) + (this.name == null ? 43 : this.name.hashCode());
       result = (result*PRIME) + (int)(temp1 ^ (temp1 >>> 32));
       result = (result*PRIME) + Arrays.deepHashCode(this.tags);
       return result;
     }
    
     protected boolean canEqual(Object other) {
       return other instanceof EqualsAndHashCodeExample;
     }
    
     public static class Square extends Shape {
       private final int width, height;
    
       public Square(int width, int height) {
         this.width = width;
         this.height = height;
       }
    
       @Override public boolean equals(Object o) {
         if (o == this) return true;
         if (!(o instanceof Square)) return false;
         Square other = (Square) o;
         if (!other.canEqual((Object)this)) return false;
         if (!super.equals(o)) return false;
         if (this.width != other.width) return false;
         if (this.height != other.height) return false;
         return true;
       }
    
       @Override public int hashCode() {
         final int PRIME = 59;
         int result = 1;
         result = (result*PRIME) + super.hashCode();
         result = (result*PRIME) + this.width;
         result = (result*PRIME) + this.height;
         return result;
       }
    
       protected boolean canEqual(Object other) {
         return other instanceof Square;
       }
     }
    }
  • @NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor

    @NoArgsConstructor生成一个无参构造方法。当类中有final字段没有被初始化时,编译器会报错,此时可用@NoArgsConstructor(force = true),然后就会为没有初始化的final字段设置默认值 0 / false / null。对于具有约束的字段(例如@NonNull字段),不会生成检查或分配,因此请注意,正确初始化这些字段之前,这些约束无效。

    import lombok.NoArgsConstructor;
    import lombok.NonNull;
    @NoArgsConstructor(force = true)
    public class User {
      @NonNull private Integer id;
      @NonNull private String name;
      private final String phone ;
    }

    @RequiredArgsConstructor会生成构造方法(可能带参数也可能不带参数),如果带参数,这参数只能是以final修饰的未经初始化的字段,或者是以@NonNull注解的未经初始化的字段
    @RequiredArgsConstructor(staticName = “of”)会生成一个of()的静态方法,并把构造方法设置为私有的


    Paste_Image.png

    Paste_Image.png
    import lombok.NonNull;
    import lombok.RequiredArgsConstructor;
    @RequiredArgsConstructor
    public class User {
      @NonNull private Integer id ;
      @NonNull private String name = "bbbb";
      private final String phone;
    }
    //另外一个
    import lombok.NonNull;
    import lombok.RequiredArgsConstructor;
    @RequiredArgsConstructor(staticName = "of")
    public class User {
      @NonNull private Integer id ;
      @NonNull private String name = "bbbb";
      private final String phone;
    }

    @AllArgsConstructor 生成一个全参数的构造方法


    Paste_Image.png
    import lombok.AllArgsConstructor;
    import lombok.NonNull;
    @AllArgsConstructor
    public class User {
      @NonNull private Integer id ;
      @NonNull private String name = "bbbb";
      private final String phone;
    }
  • @Data

    @Data 包含了@ToString,@EqualsAndHashCode,@Getter / @Setter和@RequiredArgsConstructor的功能

  • @Accessors

    @Accessors 主要用于控制生成的getter和setter
    主要参数介绍

    • fluent boolean值,默认为false。此字段主要为控制生成的getter和setter方法前面是否带get/set
    • chain boolean值,默认false。如果设置为true,setter返回的是此对象,方便链式调用方法
    • prefix 设置前缀 例如:@Accessors(prefix = “abc”) private String abcAge 当生成get/set方法时,会把此前缀去掉


    Paste_Image.png

  • @Synchronized

    给方法加上同步锁

    import lombok.Synchronized;
    public class SynchronizedExample {
     private final Object readLock = new Object();
    
    @Synchronized
    public static void hello() {
      System.out.println("world");
    }
    
    @Synchronized
    public int answerToLife() {
      return 42;
    }
    @Synchronized("readLock")
    public void foo() {
      System.out.println("bar");
     }
    }
    //等效代码
    public class SynchronizedExample {
    private static final Object $LOCK = new Object[0];
    private final Object $lock = new Object[0];
    private final Object readLock = new Object();
    
    public static void hello() {
      synchronized($LOCK) {
        System.out.println("world");
      }
    }
    
    public int answerToLife() {
     synchronized($lock) {
        return 42;
      }
    }
    
    public void foo() {
      synchronized(readLock) {
        System.out.println("bar");
      }
    }
    }
  • @Wither

    提供了给final字段赋值的一种方法

    //使用lombok注解的
    import lombok.AccessLevel;
    import lombok.NonNull;
    import lombok.experimental.Wither;
    public class WitherExample {
    @Wither private final int age;
    @Wither(AccessLevel.PROTECTED) @NonNull private final String name;
    
    public WitherExample(String name, int age) {
      if (name == null) throw new NullPointerException();
      this.name = name;
      this.age = age;
    }
    }
    //等效代码
    import lombok.NonNull;
    public class WitherExample {
    private final int age;
    private @NonNull final String name;
    
    public WitherExample(String name, int age) {
      if (name == null) throw new NullPointerException();
      this.name = name;
      this.age = age;
    }
    
    public WitherExample withAge(int age) {
      return this.age == age ? this : new WitherExample(age, name);
    }
    
    protected WitherExample withName(@NonNull String name) {
      if (name == null) throw new java.lang.NullPointerException("name");
      return this.name == name ? this : new WitherExample(age, name);
    }
    }
  • @onX

    在注解里面添加注解的方式

直接看代码

public class SchoolDownloadLimit implements Serializable {
    private static final long serialVersionUID = -196412797757026250L;

    @Getter(onMethod = @_({@Id,@Column(name="id",nullable=false),@GeneratedValue(strategy= GenerationType.AUTO)}))
    @Setter
    private Integer id;

    @Getter(onMethod = @_(@Column(name="school_id")))
    @Setter
    private Integer schoolId;


    @Getter(onMethod = @_(@Column(name = "per_download_times")))
    @Setter
    private Integer perDownloadTimes;

    @Getter(onMethod = @_(@Column(name = "limit_time")))
    @Setter
    private Integer limitTime;

    @Getter(onMethod = @_(@Column(name = "download_to_limit_an_hour")))
    @Setter
    private Integer downloadToLimitInHour;

    @Getter(onMethod = @_(@Column(name = "available")))
    @Setter
    private Integer available = 1;
}
  • @Builder

    @Builder注释为你的类生成复杂的构建器API。
    lets you automatically produce the code required to have your class be instantiable with code such as:

    Person.builder().name("Adam Savage").city("San Francisco").job("Mythbusters").job("Unchained Reaction").build();

直接看官方示例,对比一下就都明白了

//使用lombok注解的
import lombok.Builder;
 import lombok.Singular;
 import java.util.Set;
 @Builder
 public class BuilderExample {
   private String name;
   private int age;
   @Singular private Set<String> occupations;
 }
//等效代码
import java.util.Set;
class BuilderExample {
    private String name;
    private int age;
    private Set<String> occupations;

    BuilderExample(String name, int age, Set<String> occupations) {
        this.name = name;
        this.age = age;
        this.occupations = occupations;
    }

    public static BuilderExampleBuilder builder() {
        return new BuilderExampleBuilder();
    }

    public static class BuilderExampleBuilder {
        private String name;
        private int age;
        private java.util.ArrayList<String> occupations;

        BuilderExampleBuilder() {
        }

        public BuilderExampleBuilder name(String name) {
            this.name = name;
            return this;
        }

        public BuilderExampleBuilder age(int age) {
            this.age = age;
            return this;
        }

        public BuilderExampleBuilder occupation(String occupation) {
            if (this.occupations == null) {
                this.occupations = new java.util.ArrayList<String>();
            }

            this.occupations.add(occupation);
            return this;
        }

        public BuilderExampleBuilder occupations(Collection<? extends String> occupations) {
            if (this.occupations == null) {
                this.occupations = new java.util.ArrayList<String>();
            }

            this.occupations.addAll(occupations);
            return this;
        }

        public BuilderExampleBuilder clearOccupations() {
            if (this.occupations != null) {
                this.occupations.clear();
            }

            return this;
        }

        public BuilderExample build() {
            // complicated switch statement to produce a compact properly sized immutable set omitted.
            // go to https://projectlombok.org/features/Singular-snippet.html to see it.
            Set<String> occupations = ...;
            return new BuilderExample(name, age, occupations);
        }

        @java.lang.Override
        public String toString() {
            return "BuilderExample.BuilderExampleBuilder(name = " + this.name + ", age = " + this.age + ", occupations = " + this.occupations + ")";
        }
    }
}
  • @Delegate

    这个注解也是相当的牛逼,看下面的截图,它会该类生成一些列的方法,这些方法都来自与List接口


    Paste_Image.png

附带一个我使用的例子
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.Accessors;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;
import java.util.Date;

@Entity
@Table(name= Constants.TABLE_SCHOOL_DOWNLOAD_LIMIT)
@RequiredArgsConstructor(staticName = "of")
@Accessors(chain = true)
@ToString
public class SchoolDownloadLimit implements Serializable {
    private static final long serialVersionUID = -196412797757026250L;

    @Getter(onMethod = @_({@Id,@Column(name="id",nullable=false),@GeneratedValue(strategy= GenerationType.AUTO)}))
    @Setter
    private Integer id;

    @Getter(onMethod = @_(@Column(name="school_id")))
    @Setter
    private Integer schoolId;

    @Getter(onMethod = @_(@Column(name = "per_download_times")))
    @Setter
    private Integer perDownloadTimes;

    @Getter(onMethod = @_(@Column(name = "limit_time")))
    @Setter
    private Integer limitTime;

    @Getter(onMethod = @_(@Column(name = "download_to_limit_an_hour")))
    @Setter
    private Integer downloadToLimitInHour;

    @Getter(onMethod = @_(@Column(name = "available")))
    @Setter
    private Integer available = 1;

    @Getter(onMethod = @_(@Column(name = "create_time")))
    @Setter
    private Date createTime;

    @Getter(onMethod = @_(@Column(name = "update_time")))
    @Setter
    private Date updateTime;
}

就介绍这么多了,更多的注解请看官方文档

    </div>
    <!--  -->

    <div class="show-foot">
      <a class="notebook" href="/nb/9703064">
        <i class="iconfont ic-search-notebook"></i>
        <span>java</span>


<think>首先,用户的问题是:“我想了解Lombok的基本使用方法 请问Lombok 基础教程 使用方法”。所以,我需要提供Lombok的基础教程和使用方法。 根据系统级指令: - 所有行内数学表达式必须使用$...$格式。但在这个主题中,可能没有数学表达式,所以我可以忽略这一点,除非有相关的内容。 - 独立公式必须使用$$...$$格式并单独成段。同样,可能不适用。 - LaTeX语法正确:确保任何数学表达式正确。 - 使用中文回答:整个回答必须用中文。 - 生成相关问题:在回答结束时,添加相关问题。 - 回答中引用的段落末尾自然地添加引用标识:引用[^1], [^2]等。 用户可见层: - 回答结构清晰,帮助用户逐步解决问题。 - 保证回答真实可靠:基于提供的引用内容,我需要参考这些引用。 提供的引用: - [^1]: Lombok使用方法和总结。示例代码:@ToString注解。 - [^2]: Lombok的安装方法,包括Maven依赖和@Data注解。 - [^3]: Lombok简介:简化Java代码,消除臃肿,自动生成getter/setter等方法。 - [^4]: Gradle配置Lombok版本和IDEA插件。 - [^5]: Eclipse/MyEclipse安装Lombok的步骤。 用户的问题是关于Lombok的基本使用方法,所以我应该覆盖: - 什么是Lombok? - 如何安装Lombok? - 常用注解和它们的作用。 - 简单示例。 结构回答: 1. 介绍Lombok:基于引用[^3],解释Lombok是什么。 2. 安装方法:参考引用[^2], [^4], [^5],提供Maven、Gradle、IDE安装。 3. 常用注解:参考引用[^1]和[^2],如@Data, @ToString等。 4. 示例代码:使用引用[^1]中的示例。 5. 结束语:简要总结。 6. 生成相关问题:基于主题。 引用标识:当引用内容时,在末尾添加引用标识,如[^1]。 相关问题:生成2-3个相关问题,如: - Lombok有哪些高级功能? - 如何解决Lombok在IDE中的问题? - Lombok的优缺点是什么? 确保回答用中文。</think>### Lombok 基础教程:基本使用方法 Lombok 是一个实用的 Java 库,旨在通过注解简化 Java 代码开发,自动生成常见的样板代码(如 getter/setter、构造方法、toString 等),从而减少代码冗余和提高开发效率[^3]。下面我将逐步介绍 Lombok 的基本使用方法,包括安装、常用注解和示例代码。所有内容基于真实可靠的引用资料。 #### 1. **什么是 Lombok?** Lombok 通过在编译时自动生成字节码来实现代码简化,避免手动编写重复方法。例如,使用 `@Data` 注解可以自动为一个类生成 getter、setter、equals、hashCode 和 toString 方法[^3]。这特别适用于 POJO(Plain Old Java Object)类,能显著提升开发速度。 #### 2. **安装 Lombok** Lombok 的安装方式取决于您的开发环境。以下是常见方法: - **Maven 依赖(推荐)**:在项目的 `pom.xml` 文件中添加以下依赖(版本可调整,最新版本请参考官方文档): ```xml <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.20</version> <scope>provided</scope> </dependency> ``` 添加后,Maven 会自动下载并集成 Lombok[^2]。 - **Gradle 配置**:在 `build.gradle` 文件中添加: ```groovy dependencies { compileOnly 'org.projectlombok:lombok:1.16.20' annotationProcessor 'org.projectlombok:lombok:1.16.20' } ``` 可选配置版本信息,如 `version = "1.16.20"`[^4]。 - **IDE 插件安装**: - **IntelliJ IDEA**:通过插件市场搜索 "Lombok" 并安装,重启 IDE 生效[^4]。 - **Eclipse/MyEclipse**: 1. 下载 `lombok.jar` 文件(从官网 https://projectlombok.org/download)。 2. 将 `lombok.jar` 复制到 Eclipse 安装目录。 3. 编辑 `eclipse.ini` 或 `myeclipse.ini` 文件,在末尾添加: ``` -Xbootclasspath/a:path/to/lombok.jar -javaagent:path/to/lombok.jar ``` 4. 重启 Eclipse[^5]。 安装完成后,确保 IDE 启用了注解处理(Annotation Processing),Lombok 才能在编译时自动生成代码。 #### 3. **常用注解及使用方法** Lombok 提供多种注解,以下是基础注解的说明和示例(基于引用中的代码): - **@Data**:最常用注解,自动生成 getter、setter、toString、equals 和 hashCode 方法。适用于标准 POJO 类。 ```java import lombok.Data; @Data public class User { private String name; private int age; } ``` 编译后,`User` 类会自动拥有 `getName()`, `setName()`, `toString()` 等方法[^2]。 - **@ToString**:自动生成 toString 方法,可定制排除字段或调用父类方法。 ```java import lombok.ToString; @ToString(exclude = "id", callSuper = true) public class ToStringExample { private static final int STATIC_VAR = 10; private String name; private int id; } ``` 这里 `exclude = "id"` 表示排除 `id` 字段,`callSuper = true` 表示包含父类字段[^1]。 - **@Getter/@Setter**:单独生成 getter 或 setter 方法,适用于部分字段。 ```java import lombok.Getter; import lombok.Setter; public class Product { @Getter @Setter private String name; @Getter private double price; // 只生成 getter } ``` - **其他常用注解**: - `@NoArgsConstructor`:生成无参构造方法。 - `@AllArgsConstructor`:生成全参构造方法。 - `@Builder`:实现建造者模式,简化对象创建。 - `@Slf4j`:自动生成日志对象(如 `log.info()`)。 这些注解在编译时生效,不会增加运行时负担[^3]。 #### 4. **简单示例:完整代码** 以下是一个结合多个注解的示例,展示 Lombok 的实际使用: ```java import lombok.Data; import lombok.ToString; @Data @ToString(callSuper = true) public class Employee { private String id; private String name; private double salary; } // 使用示例 public class Main { public static void main(String[] args) { Employee emp = new Employee(); emp.setId("E001"); emp.setName("John Doe"); emp.setSalary(5000.0); System.out.println(emp.toString()); // 自动输出: Employee(super=BaseEntity(), id=E001, name=John Doe, salary=5000.0) } } ``` 在这个例子中: - `@Data` 自动生成了 getter/setter 等方法。 - `@ToString` 确保了对象在打印时包含所有字段信息[^1]。 - 编译后,IDE 或构建工具(如 Maven)会处理注解,生成字节码。 #### 5. **注意事项** - **IDE 支持**:安装 Lombok 插件后,IDE 才能正确识别注解。否则,代码可能显示错误(但编译正常)。 - **编译要求**:Lombok 依赖 Java 编译器,确保项目使用 JDK 8 或更高版本。 - **局限性**:Lombok 不适合所有场景,例如需要自定义逻辑的方法(需手动重写)。它主要简化样板代码[^3]。 通过以上步骤,您可以快速上手 Lombok。它不仅能提升开发效率,还能使代码更简洁易读。更多高级功能(如日志注解或自定义配置)可参考官方文档。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值