lombok的介绍、使用、简单分析和插件
学习下Lombok。
关于POJO
Java面向对象编程中的特性中有封闭性和安全性。封闭性即对类中的域变量进行封闭操作,即用private来修饰他们。如此一来,其他类就不能对该变量访问了。这样,我们就将这些变量封闭在了类的内部,提高了数据的安全性。
当我们想要操作这些域变量的时候,有两种办法。第一种是通过public方式的构造器(或称构造函数),对象一实例化就对该变量赋值。第二种就是通过set和get方法对变量进行赋值和取值。这样就能提高域变量的安全性,同时又保证了域变量的封装型。
所以当我们创建POJO类时,都会毫不犹豫的让开发工具对域变量生成set、get方法。虽然不是我们自己手动添加(快捷键或菜单快速生成),但每个类都要做重复的生成操作也是一件很烦人的事。而且当变量名或者是修饰符改变了的话,我们就要删除set、get方法并重新生成,又是一项重复又枯燥的操作。Lombok就是一个为了提高生产效率,让我们免去这些重复操作的神器。
Lombok的介绍
Project Lombok makes java a spicier language by adding 'handlers' that know how to build and compile simple, boilerplate-free, not-quite-java code.
上面这段话是官方的介绍,意思是Lombok通过一些特殊的处理,可以让Java编程变得简洁和快速。
Lombok的使用
Lombok能以简单的注解形式来简化Java代码的编写,提高开发人员的开发效率。比如在编译时自动为属性生成构造器、getter/setter、equals、hashcode、toString方法。意思就是说,在源码中不需要编写getter和setter方法,但是在编译生成的字节码文件中却会有getter和setter方法。这样就省去了手动重建这些代码的麻烦,使代码看起来更简洁些。
使用Lombok需要引用Jar包依赖,而在Maven中添加依赖十分简单。
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
<scope>provided</scope>
</dependency>
下面是Lombok提供的一些常用注解的介绍与使用。
@Data注解
@Data注解使用在类上,会为类的所有属性自动生成setter/getter、equals、canEqual、hashCode、toString方法。要注意的是,如果是final修饰符修饰的属性,则不会为该属性生成setter方法。
@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;
}
}
在开发中建议尽量少直接使用@Data注解,而是换成@Setter、@Getter、@NoArgsConstructor、@AllArgsConstructor、@ToString。
@Getter/@Setter注解
因为@Data集合了@ToString、@EqualsAndHashCode、@Getter/@Setter、@RequiredArgsConstructor的所有特性,很多时候我们可能并不需要那么多的特性,因此Lombok提供了更精细的注解@Getter/@Setter,这个注解使用在属性上会为该属性自动生成getter/setter方法。
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);
    }
}
@NonNull注解
@NonNull注解使用在属性或构造器上,Lombok会生成一个非空的声明,可用于校验参数,能帮助避免空指针。
public class NonNullExample extends Something {
    private String name;
    public NonNullExample(@NonNull Person person) {
        super("Hello");
        this.name = person.getName();
    }
}
如果不使用@NonNull注解,则要手动对属性/构造器进行非空校验。
public class NonNullExample extends Something {
    private String name;
    public NonNullExample(Person person) {
        super("Hello");
        if (person == null) {
            throw new NullPointerException("person");
        }
        this.name = person.getName();
    }
}
@Cleanup注解
@Cleanup注解能帮助我们自动调用close()方法,很大程度上简化了代码。
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注解,则需要手动调用colse()关闭输入/输出流。
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();
            }
        }
    }
}
@EqualsAndHashCode注解
默认情况下,会使用所有非静态(non-static)和非瞬态(non-transient)属性来生成equals和hasCode,也能通过exclude注解来排除一些属性。
@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 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;
        }
    }
}
@ToString注解
在类上使用@ToString注解,Lombok会生成一个toString()方法,默认情况下,会输出类名、所有属性(会按照属性定义顺序),用逗号来分割。
而通过将includeFieldNames参数设为true,就能明确的输出toString()属性。
@ToString(exclude="id")
public class ToStringExample {
private static final int STATIC_VAR = 10;
private String name;
private Shape shape = new Square(5, 10);
private String[] tags;
private int id; public String getName() {
return this.getName();
} @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;
}
}
}
@NoArgsConstructor、@RequiredArgsConstructor和@AllArgsConstructor注解
三个注解分别对应无参构造器、部分参数构造器和全参构造器。Lombok没法实现多种参数构造器的重载。
@RequiredArgsConstructor(staticName = "of")
@AllArgsConstructor(access = AccessLevel.PROTECTED)
public class ConstructorExample<T> {
private int x, y; @NonNull
private T description; @NoArgsConstructor
public static class NoArgsExample {
@NonNull
private String field;
}
}
加上staticName参数会生成一个of()的静态方法。
默认生成的方法事public的,如果想要生成其他方法修饰符修饰的方法,可以设置access参数。
Lombok简单分析
Lombok的基本原理是在编译的时候通过解析注解去自动生成相应的代码。JDK5在引入注解的同时,提供了两种解析注解的方式,一种是运行时解析,一种是编译时解析。
运行时编译
运行时能够解析的注解,必须是将注解定义中的@Retention注解设置为RUNTIME,这样才可以通过Java的反射机制拿到使用注解的类信息。在java.lang.reflect反射包中提供了一个AnnotatedElement接口,这个接口定义了获取注解信息的几个方法,Class、Constructor、Field、Method和Package等都实现了这个接口。
编译时解析
编译时的解析有两种机制:
1.Annotation Processing Tool(apt)
apt自JDK5产生,在JDK7已经被标记为过期,不推荐使用,且在JDK8中已经被彻底删除了。自JDK6开始可以使用Pluggable Annotation Processing API来替换它。apt被替换的原因主要有两个,一个是它的api都在com.sun.mirror非标准包下,一个是它没有被集成到javac中,需要额外运行。
2.Pluggable Annotation Processing API(JSR 269)
JSR 269自JDK6加入,作为apt的替代方案,它解决了apt的两个问题,javac在执行的时候会调用实现了该API的程序,这样我们可以对编译器做一些增强。
事实上,Lombok本质上就是一个实现了JSR 269 API的程序。
Lombok的插件
Lombok的插件是提供给IDE的,目的是为了方便开发者在编写源码的时候能看到Lombok通过注解自动生成的代码,没有安装插件的情况下也可能会发生编译错误。
Idea安装Lombok插件
Idea可以到插件库(Plugins)中搜索Lombok Plugin直接安装,简单又方便。
Eclipse安装Lombok插件
Eclipes则需要到官网下载插件到本地,再通过命令行安装插件。
1.到官网下载Lombok插件:https://projectlombok.org/download.html。
2.命令行切换到Lombok插件的下载目录,运行命令:java -jar lombok.jar。
3.在弹出的可视化界面中选择Eclipse的安装/解压目录并点击Install/Update即可。
安装完成之后,Eclipse的安装/解压路径下会多出一个lombok.jar文件,并且其eclipse.ini配置文件也会添加两行Lombok配置的代码:
-javaagent:lombok.jar
-Xbootclasspath/a:lombok.jar
这样,在添加完Lombok提供的注解之后就可以在Outline中查看到Lombok自动生成的代码了。
总结
Lombok是个好东西,能有效提高开发效率,使代码变得简洁,维护起来也变得简单了。但是有一个大的缺点就是Lombok不支持多个参数的构造器重载。
另外要注意的是,手动写的代码会覆盖Lombok自动生成的代码。比如如果在源代码中手写了getter/setter方法的话,会覆盖Lombok生成的getter/setter方法,或者说Lombok在编译的时候就不会去生成已经存在的getter/setter。
"如果必须完成一件自己不喜欢的事,最好的做法就是尽可能快地将这件事做好,然后无后续地结束。"
lombok的介绍、使用、简单分析和插件的更多相关文章
- 插件lombok的介绍安装
		
Lombok插件 介绍一个不错的Eclipse插件Lombok 该插件对Log4j简化的代码,因为不大,所以jar包也存在呢! Lombox是Eclipse的一个插件,用来自动生成Java代码,减少手 ...
 - CSipSimple 简单分析
		
简介 CSipSimple是一款可以在android手机上使用的支持sip的网络电话软件,可以在上面设置使用callda网络电话.连接使用方式最好是使用wifi,或者3g这样上网速度快,打起电话来效果 ...
 - 接口测试从未如此简单 - Postman (Chrome插件)
		
接口测试从未如此简单 - Postman (Chrome插件) 一个非常有力的Http Client工具用来测试Web服务的, 我这里来介绍如何用它测试restful web service 注:转载 ...
 - 简单分析Java的HashMap.entrySet()的实现
		
关于Java的HashMap.entrySet(),文档是这样描述的:这个方法返回一个Set,这个Set是HashMap的视图,对Map的操作会在Set上反映出来,反过来也是.原文是 Returns ...
 - WebRTC介绍及简单应用
		
WebRTC介绍及简单应用 WebRTC,即Web Real-Time Communication,web实时通信技术.简单地说就是在web浏览器里面引入实时通信,包括音视频通话等. WebRTC实时 ...
 - FFmpeg源码简单分析:libswscale的sws_scale()
		
===================================================== FFmpeg的库函数源码分析文章列表: [架构图] FFmpeg源码结构图 - 解码 FFm ...
 - AbstractQueuedSynchronizer的简单分析
		
说明:本作者是文章的原创作者,转载请注明出处:本文地址:http://www.cnblogs.com/qm-article/p/7955781.html 一.AbstractQueuedSynchro ...
 - FFmpeg的HEVC解码器源代码简单分析:CTU解码(CTU Decode)部分-TU
		
===================================================== HEVC源代码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpe ...
 - FFmpeg的HEVC解码器源代码简单分析:解码器主干部分
		
===================================================== HEVC源代码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpe ...
 
随机推荐
- idea修改filetype
			
settings/editor/file types把不小心改成Text类型的文件的wildcard去掉即可.
 - web自动化测试
			
自动化测试主要分为下面三种: 1.单元测试(Unit Test) 对单独的代码块,比如函数进行测试.单元测试是自动化测试的主要形式,也是最基本的形式. 2.集成测试(Integration Test) ...
 - 大白话说GIT常用操作,常用指令git操作大全
			
列一下在开发中用的比较多的git指令 git clone https://github.com/chineseLiao/Small-career // 克隆远程仓库到本地 git add . // 把 ...
 - Docker 安装mysql以及外部访问
			
(1)因为我们的镜像是linux环境下的,我所在的系统是windows系统.首先通过docker客户端切换到linux环境下. (2)使用docker pull mysql/mysql-server ...
 - vue学习指南:第十篇(详细) - Vue的 动画
			
Vue 提供了一些不同的过度效果,主要根 v-if v-show 动态组件 1. Vue给动画分了6个过程,在css中,扮演6个类, 1. .v-enter定义动画的开始状态 2. .v-ente ...
 - AI2(App Inventor 2)离线版服务器(AI伴侣2.47版)
			
提供这个版本的原因: 与app.gzjkw.net的源代码版本尽可能的接近,这样导入app.gzjkw.net源文件的时候不会有“该项目由新版App Inventor系统创建,我们仍然尝试将其加载,但 ...
 - 一个简单servlet容器
			
一个简单servlet容器 2.1 javax.servlet.Servlet接口 Servlet编程需要使用javax.servlet和javax.servlet.http两个包下的接口和类 在所有 ...
 - git使用笔记(第一次)
			
背景:公司基于微服务的架构,前端的服务web只有一个.在并行完成不同需求的测试任务时,该服务会拉出不同分支,此时会碰到sit环境与其他测试小伙伴部署冲突的问题.解释下.需求1对应的服务web的A分支, ...
 - C++编译错误 --- 成员函数定义在 .h 文件中出现重定义错误(Error LNK 2005)
			
今天写了一个简单的类,定义在 .h 文件中, 类很简单就将其成员函数定义在了一起(class类后面).运行的时候出现了如下图所示的编译错误(error LNK2005) 查资料,大部分都是说需要加上 ...
 - 从写下第1个脚本到年薪30W,我的自动化测试心路历程
			
我希望我的故事能够激励现在的软件测试人,尤其是还坚持在做“点点点”的测试人. 你可能会有疑问:“我也能做到这一点的可能性有多大?”因此,我会尽量把自己做决定和思考的过程讲得更具体一些,并尽量体现更多细 ...