Java,作为一款非常热门的编程语言,尽管它有着非常丰富的语言特性,完全面向对象编程,编程高度规范化,但是也有一个最受大家诟病的一个缺点:啰嗦,尤其是当你开发了很多年之后,你会明显的感受到,相比动态语言,java 定义变量之前,要先创建类,然后定义变量类型,每个类要写很多的get/set/toString/hashCode/equals等等方法。
尤其是当一个实体类,高达几十个变量时,写完get、set方法之后,一个实体类的长度快接近一千行。
为了避免写这些“罗嗦”的方法,很多程序员一直在寻觅着找一个能够使他们摆脱这种重复劳动工作的工具,例如:idea、eclipse 开发工具的快捷生成get、set方法的工具,还有我们今天要谈论的这个Lombok工具。
Lombok 是一款非常流行的代码简洁工具,利用它的注解特性,直接就可以帮我们省去高大几百行的get、set方法,操作非常方便。
如果是idea开发工具,可以直接在preferences -> plugins里面搜索lombok,然后点击安装即可!
接着,在项目工程中导入lombok依赖包!
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version> <scope>provided</scope> </dependency>
最后,只需要在对应的实体类上加上@Data注解,即可完成类属性get/set的注入。
import lombok.Data; @Data public class User { private String id; private String age; private String name; //可以不用显式写get、set方法 }
使用@Data注解在类上,这个实体类中的属性就不需要显式写get、set方法了。
对这个类进行编译之后,我们打开User.class文件,看看编译后的文件内容长啥样?
public class User { private String id; private String age; private String name; public User() { } public String getId() { return this.id; } public String getAge() { return this.age; } public String getName() { return this.name; } public void setId(String id) { this.id = id; } public void setAge(String age) { this.age = age; } public void setName(String name) { this.name = name; } public boolean equals(Object o) { if (o == this) { return true; } else if (!(o instanceof User)) { return false; } else { User other = (User)o; if (!other.canEqual(this)) { return false; } else { label47: { Object this$id = this.getId(); Object other$id = other.getId(); if (this$id == null) { if (other$id == null) { break label47; } } else if (this$id.equals(other$id)) { break label47; } return false; } Object this$age = this.getAge(); Object other$age = other.getAge(); if (this$age == null) { if (other$age != null) { return false; } } else if (!this$age.equals(other$age)) { return false; } Object this$name = this.getName(); Object other$name = other.getName(); if (this$name == null) { if (other$name != null) { return false; } } else if (!this$name.equals(other$name)) { return false; } return true; } } } protected boolean canEqual(Object other) { return other instanceof User; } public int hashCode() { int PRIME = true; int result = 1; Object $id = this.getId(); int result = result * 59 + ($id == null ? 43 : $id.hashCode()); Object $age = this.getAge(); result = result * 59 + ($age == null ? 43 : $age.hashCode()); Object $name = this.getName(); result = result * 59 + ($name == null ? 43 : $name.hashCode()); return result; } public String toString() { return "User(id=" + this.getId() + ", age=" + this.getAge() + ", name=" + this.getName() + ")"; } }
很清晰的看到,使用@Data注解之后,User类新增了get、set、hashCode、equals和toString方法。
通过上面的例子,大家可以发现,使用@Data注解可以大大减少了代码量,使代码非常简洁,这也是很多开发者热衷于使用Lombok的主要原因。
Lombok的工作原理是怎么实现的呢?
由于Java的官方版本没有提供这种快速生成方法的注解工具,类似Lombok这样的工具,其实都是使用了从Java 6和JSR 269的Annotation Processing技术中实现方法的注入。
简单的说,就是使用了 Java 非公开的 API,在 javac 编译代码时,通过强类型转换获取JavacAnnotationProcessor对象,再从JavacAnnotationProcessor的方法里面拿到抽象语法树(AST)做强制修改,注入get、set等方法。
使用Lombok这种方案,有个最大的好处,就是可以节省大量的重复代码,让代码更佳简洁!但是也有很多弊端!
3.1、强迫队友也安装 Lombok
当你在使用Lombok工具插件来快速开发项目的时候,如果别的同事也要和你一起协作开发项目,那么他不得不也要安装Lombok插件,不然项目编译会报错。
3.2、代码可调试性降低
代码可调试性会降低,为什么会这么说呢?
Lombok虽然给我们节省了get和set方法的编程,但是如果我想知道类的某个属性被哪些方法操作给set了,如果用原生的方法,可以很好的知道调用方。但是如果使用Lombok插件来生成,这个时候你根本无从得知。甚至没办法调试!
3.3、不懂 Lombok 注解,会踩坑
我们知道,使用@Data会重写hashCode()和equals()方法,如果是单个实体类,没有继承的话,你使用@Data不会产生问题。
但是如果这个实体类又继承了父类,@Data只会重写子类的hashCode()和equals()方法,不会把父类的属性加进去,这样就会导致,例如当你在使用HashMap的时候,用当前这个实体类作为key,可能会得到意想不到的结果。
遇到这种情况,你可以在类上加上这个注解@EqualsAndHashCode(callSuper=true),子类的hashCode()和equals()方法会加入父类的属性。
3.4、破坏封装性
封装是 java 面向对象编程中非常重要的一个特性。
例如,针对User实体类,我新家一个tag属性,我只想暴露它的get方法,不想暴露set方法给外部,没有用@Data注解的时候,我可以很灵活的进行编程,但是使用@Data注解之后,属性tag被完全暴露在外界了。
public class User { private String id; private String age; private String name; private String tag = "学生"; public String getTag() { return tag; } }
3.5、影响 jdk 升级
其实以上的坑点,都不算什么很大的坑点,在我看来,最大的坑点其实就是Lombok的工作原理,使用了非官方支持的 API 接口,通过程序强制植入方式来修改类,实现get、set等方法的注入。
按照如今 JDK 的升级频率,每半年都会推出一个新的版本,但是Lombok作为一个第三方工具,并且是由开源团队维护的,那么他的迭代速度是无法保证的。
假如某天JDK把这种后门堵住了,那Lombok基本上就不能用了,到时候又是个麻烦事情。
Lombok 作为一款非常流行的工具插件,肯定有它自身的优势所在,到底建不建议在日常开发中使用,我个人其实是一个中立的态度,如果你们团队的人都喜欢它,那推荐你使用,在使用之前,最好培训一下,有哪些坑点,避免踩坑。
如果多数人不太喜欢用它,那就不推荐你使用,很多公司禁止你使用它的原因,其实这种插件有点类似那种流氓插件,工作原理不是官方所认可的方式来实现,假如某天新版本的 jdk 突然把这个漏洞给堵住了,那么项目想要升级 jdk,就比较困难。
因此大家在评估要不要在代码中引入Lombok的时候,在想它的优点同时,能够考虑到它会带来的哪些问题,那么本文的目的也就达到了!
文章浏览阅读1k次。通过使用ajax方法跨域请求是浏览器所不允许的,浏览器出于安全考虑是禁止的。警告信息如下:不过jQuery对跨域问题也有解决方案,使用jsonp的方式解决,方法如下:$.ajax({ async:false, url: 'http://www.mysite.com/demo.do', // 跨域URL ty..._nginx不停的xhr
文章浏览阅读2k次。关于在 Oracle 中配置 extproc 以访问 ST_Geometry,也就是我们所说的 使用空间SQL 的方法,官方文档链接如下。http://desktop.arcgis.com/zh-cn/arcmap/latest/manage-data/gdbs-in-oracle/configure-oracle-extproc.htm其实简单总结一下,主要就分为以下几个步骤。..._extproc
文章浏览阅读1.5w次。linux下没有上面的两个函数,需要使用函数 mbstowcs和wcstombsmbstowcs将多字节编码转换为宽字节编码wcstombs将宽字节编码转换为多字节编码这两个函数,转换过程中受到系统编码类型的影响,需要通过设置来设定转换前和转换后的编码类型。通过函数setlocale进行系统编码的设置。linux下输入命名locale -a查看系统支持的编码_linux c++ gbk->utf8
文章浏览阅读750次。今天准备从生产库向测试库进行数据导入,结果在imp导入的时候遇到“ IMP-00009:导出文件异常结束” 错误,google一下,发现可能有如下原因导致imp的数据太大,没有写buffer和commit两个数据库字符集不同从低版本exp的dmp文件,向高版本imp导出的dmp文件出错传输dmp文件时,文件损坏解决办法:imp时指定..._imp-00009导出文件异常结束
文章浏览阅读143次。当下是一个大数据的时代,各个行业都离不开数据的支持。因此,网络爬虫就应运而生。网络爬虫当下最为火热的是Python,Python开发爬虫相对简单,而且功能库相当完善,力压众多开发语言。本次教程我们爬取前程无忧的招聘信息来分析Python程序员需要掌握那些编程技术。首先在谷歌浏览器打开前程无忧的首页,按F12打开浏览器的开发者工具。浏览器开发者工具是用于捕捉网站的请求信息,通过分析请求信息可以了解请..._初级python程序员能力要求
文章浏览阅读7.6k次,点赞2次,收藏6次。@Service标注的bean,类名:ABDemoService查看源码后发现,原来是经过一个特殊处理:当类的名字是以两个或以上的大写字母开头的话,bean的名字会与类名保持一致public class AnnotationBeanNameGenerator implements BeanNameGenerator { private static final String C..._@service beanname
文章浏览阅读6.9w次,点赞73次,收藏463次。1.前序创建#include<stdio.h>#include<string.h>#include<stdlib.h>#include<malloc.h>#include<iostream>#include<stack>#include<queue>using namespace std;typed_二叉树的建立
文章浏览阅读7.1k次。在Asp.net上使用Excel导出功能,如果文件名出现中文,便会以乱码视之。 解决方法: fileName = HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8);_asp.net utf8 导出中文字符乱码
文章浏览阅读2.1k次,点赞4次,收藏23次。第一次实验 词法分析实验报告设计思想词法分析的主要任务是根据文法的词汇表以及对应约定的编码进行一定的识别,找出文件中所有的合法的单词,并给出一定的信息作为最后的结果,用于后续语法分析程序的使用;本实验针对 PL/0 语言 的文法、词汇表编写一个词法分析程序,对于每个单词根据词汇表输出: (单词种类, 单词的值) 二元对。词汇表:种别编码单词符号助记符0beginb..._对pl/0作以下修改扩充。增加单词
文章浏览阅读773次。我在使用adb.exe时遇到了麻烦.我想使用与bash相同的adb.exe shell提示符,所以我决定更改默认的bash二进制文件(当然二进制文件是交叉编译的,一切都很完美)更改bash二进制文件遵循以下顺序> adb remount> adb push bash / system / bin /> adb shell> cd / system / bin> chm..._adb shell mv 权限
文章浏览阅读6.8k次,点赞12次,收藏125次。1. 单目相机标定引言相机标定已经研究多年,标定的算法可以分为基于摄影测量的标定和自标定。其中,应用最为广泛的还是张正友标定法。这是一种简单灵活、高鲁棒性、低成本的相机标定算法。仅需要一台相机和一块平面标定板构建相机标定系统,在标定过程中,相机拍摄多个角度下(至少两个角度,推荐10~20个角度)的标定板图像(相机和标定板都可以移动),即可对相机的内外参数进行标定。下面介绍张氏标定法(以下也这么称呼)的原理。原理相机模型和单应矩阵相机标定,就是对相机的内外参数进行计算的过程,从而得到物体到图像的投影_相机-投影仪标定
文章浏览阅读2.2k次。文章目录Wayland 架构Wayland 渲染Wayland的 硬件支持简 述: 翻译一篇关于和 wayland 有关的技术文章, 其英文标题为Wayland Architecture .Wayland 架构若是想要更好的理解 Wayland 架构及其与 X (X11 or X Window System) 结构;一种很好的方法是将事件从输入设备就开始跟踪, 查看期间所有的屏幕上出现的变化。这就是我们现在对 X 的理解。 内核是从一个输入设备中获取一个事件,并通过 evdev 输入_wayland