Java进阶教程:使用Lombok提升开发效率

Lombok

  Lombok是一种Java™实用工具,可用来帮助开发人员消除Java的冗长代码,尤其是对于简单的Java对象(POJO)。它通过注释实现这一目的。通过在开发环境中实现Lombok,开发人员可以节省构建诸如hashCode()和equals()这样的方法以及以往用来分类各种accessor和mutator的大量时间。

Lombok安装

  下面是通过Maven进行安装的,也可以在官网下载Jar包。

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

插件安装

  Lombok通过编译时根据注解插入一些相关代码,来实现其简化开发的目的。所以,在开发时,诸如Setter/Getter等都是无法进行代码提示的。IDEA推荐使用Lombok插件:

  

示例

@Val和@Var

  前者定义常量,后者定义局部变量,其类型可以自动推测,不需要明确指出。

    public static void varAndVal(var c){ //[X]不可用于形参
val a = 10; //[√]定义一个常量,其类型可自动推测
var b = 10; //[√]定义一个变量,其类型可自动推测
a++; //[X]常量无法被修改,此处报错!
b++; //[√]此处为Int类型变量,可以进行自增操作
b = "String";//[X]仍然遵循强类型规则,不可修改类型
}

@Cleanup和@SneakyThrows

  使用Cleanup以确保在代码执行路径退出当前作用域之前自动清除给定资源

    @SneakyThrows
public static void cleanUp(){
@Cleanup OutputStreamWriter writer = new OutputStreamWriter(System.out);
writer.write("Hello World");
}

  如果我们反编译该代码,Lombok自动为我们做了资源清理以及异常抛出

public static void cleanUp() {
try {
OutputStreamWriter writer = new OutputStreamWriter(System.out); try {
writer.write("Hello World");
} finally {
if (Collections.singletonList(writer).get(0) != null) {
writer.close();
} } } catch (Throwable var5) {
throw var5;
}
}

  同时我们还用了一个注解@SneakyThrows,他可以帮助我们抛出已检查的异常而开发时不需要在方法的throws子句中实际声明

@Getter和@Setter

  解放双手,不用再写访问器了!

class Hello{
@Getter
@Setter
private int a; public static void main(String[] args) {
Hello a = new Hello();
a.setA(10); //Setter
System.out.println(a.getA()); //Getter
}
}

  

@NonNull

  给方法参数增加这个注解会自动在方法内执行前对该参数进行是否为空的校验,如果为空,则抛出NPE(NullPointerException)

    //不会打印10
public static void nonNull(@NonNull HashSet a){
System.out.println(10);
System.out.println(a.size());
} //打印10后才会抛出异常,所以方法可能错误执行一部分
public static void notNull(HashSet a){
System.out.println(10);
System.out.println(a.size());
}

  加上这个注解后,实际代码如下:

    public static int nonNull(@NonNull HashSet a) {
if (a == null) {
throw new NullPointerException("a");
} else {
System.out.println(10);
System.out.println(a.size());
return 10;
}
}

@ToString

  为使用该注解的类生成一个toString方法,默认的toString格式为:ClassName(fieldName= fieleValue ,fieldName1=fieleValue)。

@ToString(includeFieldNames = true,exclude = {"a"})
class Hello{
@Getter
@Setter
private int a =10;
private double b =20.19;
private String c = "hello"; public static void main(String[] args) {
Hello a = new Hello();
System.out.println(a);
//RESULT:Hello(b=20.19, c=hello)
}
}

  

@EqualsAndHashCode

  为使用该注解的类自动生成equals和hashCode方法。

@EqualsAndHashCode
class Hello{
private int a =10;
private double b =20.19;
private String c = "hello";
}

  加注解很简单,但实际上Lombok帮我们重写了equals和hashCode方法,可见其equals是比较了字段的值以及是否为null而得出的。

    public boolean equals(Object o) {
if (o == this) {
return true;
} else if (!(o instanceof Hello)) {
return false;
} else {
Hello other = (Hello)o;
if (!other.canEqual(this)) {
return false;
} else if (this.getA() != other.getA()) {
return false;
} else if (Double.compare(this.b, other.b) != 0) {
return false;
} else {
Object this$c = this.c;
Object other$c = other.c;
if (this$c == null) {
if (other$c == null) {
return true;
}
} else if (this$c.equals(other$c)) {
return true;
} return false;
}
}
} protected boolean canEqual(Object other) {
return other instanceof Hello;
} public int hashCode() {
int PRIME = true;
int result = 1;
int result = result * 59 + this.getA();
long $b = Double.doubleToLongBits(this.b);
result = result * 59 + (int)($b >>> 32 ^ $b);
Object $c = this.c;
result = result * 59 + ($c == null ? 43 : $c.hashCode());
return result;
}

@NoArgsConstructor, @RequiredArgsConstructor, @AllArgsContructor

  • @NoArgsConstructor : 生成一个无参数的构造方法
  • @AllArgsContructor: 生成一个包含所有变量的构造方法
  • @RequiredArgsConstructor: 会生成一个包含常量和标识了NotNull的变量的构造方法。生成的构造方法是私有的private。

  对于RequiredArgsConstructor来说,它提供了一种新的构造思路,即通过静态方法,赋予其有意义的方法名,来构造对象。

    private Hello(@NonNull double b, @NonNull String c) {
if (c == null) {
throw new NullPointerException("c");
} else {
this.b = b;
this.c = c;
}
} public static Hello buildByBAndC(@NonNull double b, @NonNull String c) {
return new Hello(b, c);
}

@Data

  @Data注解作用比较全,其包含注解的集合@ToString@EqualsAndHashCode,所有字段的@Getter和所有非final字段的@Setter@RequiredArgsConstructor

@Builder

  Builder注解可以快速实现构建者模式,即通过函数来赋值字段,以及构建最终对象

@ToString
@Builder
class Hello{
private int a;
private double b;
private String c; public static void main(String[] args) {
Hello a = Hello.builder().a(11).b(12).c("hi").build();
System.out.println(a);
//RESULT:Hello(a=11, b=12.0, c=hi)
}
}

  

@Synchronized

  多线程开发时,锁定this或你自己的类对象可能会产生不幸的副作用,因为不受你控制的其他代码也可以锁定这些对象,这可能会导致竞争条件和其他讨厌的线程相关错误。

  @Synchronized注解类似Java中的Synchronized 关键字,但是可以隐藏同步锁,Lombok会自动去创建对象锁。

    @Synchronized
public static void synchDemo1(){
System.out.println("World");
}

  它实际编译的代码如下

    private static final Object $LOCK = new Object[0];

    public static void synchDemo1() {
synchronized($LOCK) {
System.out.println("World");
}
}

Lombok原理

  Lombok这款插件依靠可插件化的Java自定义注解处理API(JSR 269: Pluggable Annotation Processing API)来实现在Javac编译阶段利用“Annotation Processor”对自定义的注解进行预处理后生成真正在JVM上面执行的“Class文件”
  
  从上面的Lombok执行的流程图中可以看出,在Javac 解析成AST抽象语法树之后, Lombok 根据自己编写的注解处理器,动态地修改 AST,增加Lombok自定义注解所需要生成的代码,最终通过分析生成JVM可执行的字节码Class文件。使用Annotation Processing自定义注解是在编译阶段进行修改,而JDK的反射技术是在运行时动态修改,两者相比,反射虽然更加灵活一些但是带来的性能损耗更加大

参考链接

Java进阶教程:使用Lombok提升开发效率的更多相关文章

  1. atitit.提升开发效率---使用服务器控件生命周期 asp.net 11个阶段 java jsf 的6个阶段比较

    atitit.提升开发效率---使用服务器控件生命周期  asp.net 11个阶段  java jsf 的6个阶段比较 如下列举了服务器控件生命周期所要经历的11个阶段. (1)初始化-- --在此 ...

  2. atitit.提升开发效率---使用server控件生命周期 asp.net 11个阶段 java jsf 的6个阶段比較

    atitit.提升开发效率---使用server控件生命周期  asp.net 11个阶段  java jsf 的6个阶段比較 例如以下列举了server控件生命周期所要经历的11个阶段. (1)初始 ...

  3. Java进阶(三)多线程开发关键技术

    原创文章,同步发自作者个人博客,转载请务必以超链接形式在文章开头处注明出处http://www.jasongj.com/java/multi_thread/. sleep和wait到底什么区别 其实这 ...

  4. Atitit. 提升开发效率与质量DSL ( 3) ----实现DSL的方式总结

    Atitit. 提升开发效率与质量DSL ( 3) ----实现DSL的方式总结 1. 管道抽象 1 2. 层次结构抽象(json,xml etc) 1 3. 异步抽象promise 1 4. Ide ...

  5. atitit.提升开发效率---MDA 软件开发方式的革命(3)----自动化建表

    atitit.提升开发效率---MDA 软件开发方式的革命(3)----自动化建表 1. 建模在后自动建表 1 1. 传统上,需要首先建表,在业务编码.. 1 2. 模型驱动建表---更多简化法是在建 ...

  6. atitit.提升开发效率---mda 软件开发方式的革命--(2)

    atitit.提升开发效率---mda 软件开发方式的革命--(2) 1. 一个完整的MDA规范包含: 1 2. 一个完整的MDA应用程序包含: 1 3. MDA能够带来的最大的三个好处是什么? 2 ...

  7. atitit.提升开发效率---动态语言总结

    atitit.提升开发效率---动态语言总结 ruby,python 都不错,就是语法不好, 应用不广泛,文档,工具都非常少,不推荐... php狠不错,就是高级特性不行.. 看来子有.net/jav ...

  8. atitit.提升开发效率---MDA 软件开发方式的革命(3)----自己主动化建表

    atitit.提升开发效率---MDA 软件开发方式的革命(3)----自己主动化建表 1. 建模在后自己主动建表 1 1. 传统上,须要首先建表,在业务编码.. 1 2. 模型驱动建表---很多其它 ...

  9. atitit.提升开发效率---mda 软件开发方式的革命

    atitit.提升开发效率---mda 软件开发方式的革命 1. 软件开发方式的革命开发工具的抽象层次将再次提升 1 2. 应用框架和其实现相分离 2 3. 目前的问题模型和代码不同步 2 4. MD ...

随机推荐

  1. learning java AWT 右键菜单

    import java.awt.*; import java.awt.event.*; public class SimpleMenu { private Frame f = new Frame(&q ...

  2. 自定义mvc增删改查

    对t_mvc_book表的增删改查 导入jar包 BaseDao package com.hmc.util; import java.lang.reflect.Field; import java.s ...

  3. c语言数组的概念和指针的加减使用

    //数组变量名:就是一个地址:就是数组首元素的地址#include <stdio.h> int main(void) { int age[5] = {10,50,100,22,44}; / ...

  4. Poj 1743 Musical Theme(后缀数组+二分答案)

    Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 28435 Accepted: 9604 Descri ...

  5. flutter踩坑小记:The number of method references in a .dex file cannot exceed 64K.

    The number of method references in a .dex file cannot exceed 64K. 这句话的意思翻译出来是:.dex文件中的方法引用数不能超过64K. ...

  6. 利用HTML和CSS设计一个静态的“小米商城官网首页”

    一.小项目说明 这是个例行的小项目练习,主要利用html和css的基础知识,复刻一个缩减版的小米商城网页.包括[导航栏].[头部logo区,快捷键.搜索框].[网页主体].[网页尾部]几个部分.目前只 ...

  7. Leetcode42. 接雨水

    42. 接雨水 做法 考虑单独一列能生产多少贡献:用左右最大值去接这列的水 \(O(n)\) Code class Solution { public: int mx[1000000],rx[1000 ...

  8. jquery中$.get()如何让跨域请求携带cookie?

    在这个get请求前面加上这个就好了~~~~

  9. 批量转换word为pdf

    自己写的一个小工具,用于批量转换word为pdf,使用方式: 将完整代码拷贝到文档中,并修改名称为words2pdfs.py将该文件拷贝到需要转换的文档目录下在终端中输入python words2pd ...

  10. 记录vsCode配置node开发环境

    环境:win10,idea:vscode 1:安装Visual Studio Code 下一步下一步.(很早之前就安装了). 2:安装node. http://nodejs.cn/download/  ...