今日给大家推荐一个java开发神器-Lombok

今天为大家推荐一个java的开发神器lombok,可以帮助大家节省开发时间,提升工(mo)作(yu)效(shi)率(jian)。

一、基本介绍

Lombok是一款Java开发插件,可以通过它定义的注解来精简冗长和繁琐的代码,主要针对简单的Java模型对象(POJO)。

好处就显而易见了,可以节省大量重复工作,特别是当POJO类的属性增减时,需要重复修改的Getter/Setter、构造器方法、equals方法和toString方法等。

而且Lombok针对这些内容的处理是在编译期,而不是通过反射机制,这样的好处是并不会降低系统的性能。

目前Lombok已经支持JDK14和JDK13的一些特性

二、IDE安装Lombok开发工具

Lombok的官网中详细的介绍了各种IDE安装Lombok的方法,目前已经指出IDEA、Eclipse、Netbeans、Myeclipse、Spring boot Suite、Visual Studio Code等工具,本文以IDEA为例,介绍安装的方法,其他IDE的安装方法按照官网的方式进行安装。

2.1 在线安装

  1. 点击File -> Settings -> Plugins

  2. 在marketplace中搜索Lombok


    Lombok
  3. 点击install


    安装完成
  4. Restart IntelliJ IDEA


    重新IDEA之后

2.2 离线安装

在一些管理比较严格的公司里,开发环境不允许连接外网,离线安装的方法主要方便这些苦难的兄弟
1.进入jetbrains官网,找到Lombook插件
2.根据自己IDEA版本选择对应的版本

Lombok插件版本选择

  1. 点击File -> Settings -> Plugins,选择install plugins from disk


    image.png

    4.选择下载的插件,后续与在线安装过程一致

注意:选择下载插件时,一定要与IDEA的版本一致,如不一致,会提示不可用,或者安装失败

三、引入依赖

Lombok的官网中分别介绍了maven、gradle、ant和Kobalt四种构建工具如何引入Lombok,本文以maven为例进行简单的介绍,其他构建工具可以参考官网的文档

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.12</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

其中,1.18.12版本为当前最新版本,<scope>provided</scope> 表示编译时不会将其打包war/jar包中。

四、注解简介

Lombok的所有注解可以通过官网Lombok features查看

1. @Getter/@Setter

这两个注意应该是使用lombok中最常用的的两个注解,一个属性foo,通过@Getter注解生成的get方法的方法名为getFoo(),如果该属性为boolean,则方法名为isFoo();set方法名为setFoo,返回值为void。

@Setter/@Getter生成的方法为public,如果想要修改方法的访问修饰符,可以使用AccessLevel进行限制,AccessLevel支持所有的访问修饰符(PUBLIC、PROTECTED、PACKAGE、PRIVATE)

@Setter(AccessLevel.PROTECTED) private String name;

官网示例:
Lombok版本

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

public class GetterSetterExample {
  /**
   * Age of the person. Water is wet.
   * 
   * @param age New value for this person's age. Sky is blue.
   * @return The current value of this person's age. Circles are round.
   */
  @Getter @Setter private int age = 10;
  
  /**
   * Name of the person.
   * -- SETTER --
   * Changes the name of this person.
   * 
   * @param name The new value.
   */
  @Setter(AccessLevel.PROTECTED) private String name;
  
  @Override public String toString() {
    return String.format("%s (age: %d)", name, age);
  }
}

不使用Lombok的程序

public class GetterSetterExample {
  /**
   * Age of the person. Water is wet.
   */
  private int age = 10;

  /**
   * Name of the person.
   */
  private String name;
  
  @Override public String toString() {
    return String.format("%s (age: %d)", name, age);
  }
  
  /**
   * Age of the person. Water is wet.
   *
   * @return The current value of this person's age. Circles are round.
   */
  public int getAge() {
    return age;
  }
  
  /**
   * Age of the person. Water is wet.
   *
   * @param age New value for this person's age. Sky is blue.
   */
  public void setAge(int age) {
    this.age = age;
  }
  
  /**
   * Changes the name of this person.
   *
   * @param name The new value.
   */
  protected void setName(String name) {
    this.name = name;
  }
}

示例中的@Setter@Getter注解分别放到了具体的属性前,在开发过程中,通常直接放到类的定义前,这样表示该类中的所有属性都要生成set/get方法

2.@NonNull

作用于属性上,提供关于此参数的非空检查,如果参数为空,则抛出空指针异常。
非空检查的代码示例如下:

if (param == null) 
    throw new NullPointerException("param is marked @NonNull but is null")

官方示例:
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(Person person) {
    super("Hello");
    if (person == null) {
      throw new NullPointerException("person is marked @NonNull but is null");
    }
    this.name = person.getName();
  }
}

注意:官网中Vanilla Java版本中在Person person前增加了@NonNull 注解,应该是编写错误,此处特意进行说明

3.@NoArgsConstructor/@RequiredArgsConstructor/@AllArgsConstructor

这三个注解主要是生成构造函数的标签,其中:
@NoArgsConstructor表示生成一个不带参数的构造方法;
@RequiredArgsConstructor表示生成一些特定属性的构造方法,特定参数包括final的字段和标记@NonNull的字段;使用该标签生成的构造方法的访问修饰符为private,可以增加staticName属性值,该属性默认为“”,增加该属性后,会默认生成一个名为staticName值的构造方法,其访问修饰符为public的静态方法,参数与@RequiredArgsConstructor参数一致
@AllArgsConstructor表示生成所有属性的构造方法;

官方示例:
Lombok版本

import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import lombok.AllArgsConstructor;
import lombok.NonNull;

@RequiredArgsConstructor(staticName = "of")
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@NoArgsConstructor
public class ConstructorExample<T> {
  private int x, y;
  @NonNull private T description;
}

不带Lombok版本

public class ConstructorExample<T> {
  private int x, y;
  @NonNull private T description;
}

// @NoArgsConstructor对应的构造方法
private ConstructorExample(T description) {

}
// @RequiredArgsConstructor对应的构造方法
private ConstructorExample(T description) {
    if (description == null) throw new NullPointerException("description");
    this.description = description;
  }
  
// 增加staticName后生成的构造方法
 public static <T> ConstructorExample<T> of(T description) {
    return new ConstructorExample<T>(description);
 }
  
// @AllArgsConstructor对应的构造方法
  @java.beans.ConstructorProperties({"x", "y", "description"})
protected ConstructorExample(int x, int y, T description) {
    if (description == null) throw new NullPointerException("description");
    this.x = x;
    this.y = y;
    this.description = description;
 }

官方给出的示例让人看起来有点摸不着头脑,为了方便清楚的明白这三个标签,将官方的示例进行调整,效果可能会更好一点。

查看使用三个注解生成的方法,与不使用Lombok的构造方法完全一致


IDEA 类方法结构

4. @ToString

@ToString自动生成一个toString()方法,默认情况是所有的字段都在进行字符串输出,当然,可以使用@ToString.Exclude的方式排除一些字段不显示输出。

5.@Data

@Data注解集成了@ToString@EqualsAndHashCode@Getter / @Setter@RequiredArgsConstructor

6.@EqualsAndHashCode

@EqualsAndHashCode生成hashCode()canEqualequals()方法

7.val/var

使用val作为局部变量声明的类型,而不是实际写入类型。 执行此操作时,将从初始化表达式推断出类型。
varval几乎一样,只是变量前没有final的定义

我理解var和val与javascript中的左右几乎相同,在对变量赋值之后在进行赋值,这两个属性不是注解,是一个类,实际场景中可能的用途不是太多

官方示例:
Lombok版本


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

不带Lombok版本


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

其他的属性可以参考官网中稳定版本的特性列表,不在额外叙述

五、关于Lombok的一些争议

之前在网上有人发布Lombok是让你代码处于“亚健康”状态的真正元凶,提出Lombok存在的四个问题:

    * JDK8升级到JDK11后,Lombok不能使用
    * 胁迫使用:当你的源代码中使用了Lombok,恰好你的代码又被其他的人所使用,那么依赖你代码的人,也必须安装Lombok插件
    * 可读性差:Lombok隐藏了JavaBean封装的细节,所有JavaBean中的方法你只能想象他们长什么样子,你并不能看见
    * 代码耦合度增加:当你使用Lombok来编写某一个模块的代码后,其余依赖此模块的其他代码都需要引入Lombok依赖,同时还需要在IDE中安装Lombok的插件,这是一种入侵式的耦合

关于第一个问题,其实是Lombok的版本原因,在项目中使用了相对较低的版本,会存在升级JDK后不能使用的问题,升级到最新的Lombok就可,那会不会有有问题呢?呵呵呵,JDK都升级了还怕插件升级有问题吗?

关于第二点,的确是不可避免的事实,既然都是使用到代码级别,那应该是一个团队或者一个公司级别,换一个思路思考,那团队或者公司要求使用相同的架构和框架是不是也很合理?

关于第三个问题,实际上可以适当的选择Lombok的注解,对于不好用的注解可以选择不使用。在我看来,@Getter@Setter就可以解决我大量的工作

关于第四个问题,实际上可以使用maven的配置就可以解决相关问题,可以增加<optional>true</optional>,这样依赖可以不传给引用的项目。

参考文献

1.Project Lombok
2.Java开发神器Lombok使用详解
3.Lombok是让你代码处于“亚健康”状态的真正元凶

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,843评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,538评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,187评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,264评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,289评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,231评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,116评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,945评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,367评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,581评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,754评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,458评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,068评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,692评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,842评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,797评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,654评论 2 354