赞
踩
今天为大家推荐一个java的开发神器lombok,可以帮助大家节省开发时间,提升工(mo)作(yu)效(shi)率(jian)。
Lombok是一款Java开发插件,可以通过它定义的注解来精简冗长和繁琐的代码,主要针对简单的Java模型对象(POJO)。
好处就显而易见了,可以节省大量重复工作,特别是当POJO类的属性增减时,需要重复修改的Getter/Setter、构造器方法、equals方法和toString方法等。
而且Lombok针对这些内容的处理是在编译期,而不是通过反射机制,这样的好处是并不会降低系统的性能。
目前Lombok已经支持JDK14和JDK13的一些特性
Lombok的官网中详细的介绍了各种IDE安装Lombok的方法,目前已经指出IDEA、Eclipse、Netbeans、Myeclipse、Spring boot Suite、Visual Studio Code等工具,本文以IDEA为例,介绍安装的方法,其他IDE的安装方法按照官网的方式进行安装。
点击File -> Settings -> Plugins
在marketplace中搜索Lombok
点击install
Restart IntelliJ IDEA
在一些管理比较严格的公司里,开发环境不允许连接外网,离线安装的方法主要方便这些苦难的兄弟
1.进入jetbrains官网,找到Lombook插件
2.根据自己IDEA版本选择对应的版本
点击File -> Settings -> Plugins,选择install plugins from disk
4.选择下载的插件,后续与在线安装过程一致
注意:选择下载插件时,一定要与IDEA的版本一致,如不一致,会提示不可用,或者安装失败
Lombok的官网中分别介绍了maven、gradle、ant和Kobalt四种构建工具如何引入Lombok,本文以maven为例进行简单的介绍,其他构建工具可以参考官网的文档
1<dependencies>2 <dependency>3 <groupId>org.projectlombokgroupId>4 <artifactId>lombokartifactId>5 <version>1.18.12version>6 <scope>providedscope>7 dependency>8dependencies>
其中,1.18.12版本为当前最新版本,provided表示编译时不会将其打包war/jar包中。
Lombok的所有注解可以通过官网Lombok features查看
这两个注意应该是使用lombok中最常用的的两个注解,一个属性foo,通过@Getter
注解生成的get方法的方法名为getFoo(),如果该属性为boolean,则方法名为isFoo();set方法名为setFoo,返回值为void。
@Setter
/@Getter
生成的方法为public,如果想要修改方法的访问修饰符,可以使用AccessLevel进行限制,AccessLevel支持所有的访问修饰符(PUBLIC、PROTECTED、PACKAGE、PRIVATE)
1@Setter(AccessLevel.PROTECTED) private String name;
官网示例:
Lombok版本
1import lombok.AccessLevel; 2import lombok.Getter; 3import lombok.Setter; 4 5public class GetterSetterExample { 6 /** 7 * Age of the person. Water is wet. 8 * 9 * @param age New value for this person's age. Sky is blue.10 * @return The current value of this person's age. Circles are round.11 */12 @Getter @Setter private int age = 10;1314 /**15 * Name of the person.16 * -- SETTER --17 * Changes the name of this person.18 * 19 * @param name The new value.20 */21 @Setter(AccessLevel.PROTECTED) private String name;2223 @Override public String toString() {24 return String.format("%s (age: %d)", name, age);25 }26}
不使用Lombok的程序
1public class GetterSetterExample { 2 /** 3 * Age of the person. Water is wet. 4 */ 5 private int age = 10; 6 7 /** 8 * Name of the person. 9 */10 private String name;1112 @Override public String toString() {13 return String.format("%s (age: %d)", name, age);14 }1516 /**17 * Age of the person. Water is wet.18 *19 * @return The current value of this person's age. Circles are round.20 */21 public int getAge() {22 return age;23 }2425 /**26 * Age of the person. Water is wet.27 *28 * @param age New value for this person's age. Sky is blue.29 */30 public void setAge(int age) {31 this.age = age;32 }3334 /**35 * Changes the name of this person.36 *37 * @param name The new value.38 */39 protected void setName(String name) {40 this.name = name;41 }42}
示例中的@Setter
和@Getter
注解分别放到了具体的属性前,在开发过程中,通常直接放到类的定义前,这样表示该类中的所有属性都要生成set/get方法
作用于属性上,提供关于此参数的非空检查,如果参数为空,则抛出空指针异常。
非空检查的代码示例如下:
1if (param == null) 2 throw new NullPointerException("param is marked @NonNull but is null")
官方示例:
Lombok版本
1public class NonNullExample extends Something {2 private String name;34 public NonNullExample(@NonNull Person person) {5 super("Hello");6 this.name = person.getName();7 }8}
不带Lombok版本
1public class NonNullExample extends Something { 2 private String name; 3 4 public NonNullExample(Person person) { 5 super("Hello"); 6 if (person == null) { 7 throw new NullPointerException("person is marked @NonNull but is null"); 8 } 9 this.name = person.getName();10 }11}
注意:官网中Vanilla Java版本中在Person person前增加了@NonNull
注解,应该是编写错误,此处特意进行说明
这三个注解主要是生成构造函数的标签,其中:@NoArgsConstructor
表示生成一个不带参数的构造方法;@RequiredArgsConstructor
表示生成一些特定属性的构造方法,特定参数包括final的字段和标记@NonNull
的字段;使用该标签生成的构造方法的访问修饰符为private,可以增加staticName属性值,该属性默认为“”,增加该属性后,会默认生成一个名为staticName值的构造方法,其访问修饰符为public的静态方法,参数与@RequiredArgsConstructor
参数一致@AllArgsConstructor
表示生成所有属性的构造方法;
官方示例:
Lombok版本
1import lombok.AccessLevel; 2import lombok.RequiredArgsConstructor; 3import lombok.AllArgsConstructor; 4import lombok.NonNull; 5 6@RequiredArgsConstructor(staticName = "of") 7@AllArgsConstructor(access = AccessLevel.PROTECTED) 8@NoArgsConstructor 9public class ConstructorExample<T> {10 private int x, y;11 @NonNull private T description;12}
不带Lombok版本
1public class ConstructorExample<T> { 2 private int x, y; 3 @NonNull private T description; 4} 5 6// @NoArgsConstructor对应的构造方法 7private ConstructorExample(T description) { 8 9}10// @RequiredArgsConstructor对应的构造方法11private ConstructorExample(T description) {12 if (description == null) throw new NullPointerException("description");13 this.description = description;14 }1516// 增加staticName后生成的构造方法17 public static ConstructorExample of(T description) {18 return new ConstructorExample(description);19 }2021// @AllArgsConstructor对应的构造方法22 @java.beans.ConstructorProperties({"x", "y", "description"})23protected ConstructorExample(int x, int y, T description) {24 if (description == null) throw new NullPointerException("description");25 this.x = x;26 this.y = y;27 this.description = description;28 }
官方给出的示例让人看起来有点摸不着头脑,为了方便清楚的明白这三个标签,将官方的示例进行调整,效果可能会更好一点。
查看使用三个注解生成的方法,与不使用Lombok的构造方法完全一致
@ToString
自动生成一个toString()方法,默认情况是所有的字段都在进行字符串输出,当然,可以使用@ToString.Exclude
的方式排除一些字段不显示输出。
@Data注解集成了@ToString
、@EqualsAndHashCode
、@Getter
/ @Setter
和@RequiredArgsConstructor
@EqualsAndHashCode
生成hashCode()
、canEqual
和equals()
方法
使用val
作为局部变量声明的类型,而不是实际写入类型。执行此操作时,将从初始化表达式推断出类型。var
与val
几乎一样,只是变量前没有final的定义
我理解var和val与javascript中的左右几乎相同,在对变量赋值之后在进行赋值,这两个属性不是注解,是一个类,实际场景中可能的用途不是太多
官方示例:
Lombok版本
1import java.util.ArrayList; 2import java.util.HashMap; 3import lombok.val; 4 5public class ValExample { 6 public String example() { 7 val example = new ArrayList(); 8 example.add("Hello, World!"); 9 val foo = example.get(0);10 return foo.toLowerCase();11 }12}
不带Lombok版本
1import java.util.ArrayList; 2import java.util.HashMap; 3import java.util.Map; 4 5public class ValExample { 6 public String example() { 7 final ArrayList example = new ArrayList(); 8 example.add("Hello, World!"); 9 final String foo = example.get(0);10 return foo.toLowerCase();11 }12}
其他的属性可以参考官网中稳定版本的特性列表,不在额外叙述
之前在网上有人发布Lombok是让你代码处于“亚健康”状态的真正元凶,提出Lombok存在的四个问题:
1 * JDK8升级到JDK11后,Lombok不能使用2 * 胁迫使用:当你的源代码中使用了Lombok,恰好你的代码又被其他的人所使用,那么依赖你代码的人,也必须安装Lombok插件3 * 可读性差:Lombok隐藏了JavaBean封装的细节,所有JavaBean中的方法你只能想象他们长什么样子,你并不能看见4 * 代码耦合度增加:当你使用Lombok来编写某一个模块的代码后,其余依赖此模块的其他代码都需要引入Lombok依赖,同时还需要在IDE中安装Lombok的插件,这是一种入侵式的耦合
关于第一个问题,其实是Lombok的版本原因,在项目中使用了相对较低的版本,会存在升级JDK后不能使用的问题,升级到最新的Lombok就可,那会不会有有问题呢?呵呵呵,JDK都升级了还怕插件升级有问题吗?
关于第二点,的确是不可避免的事实,既然都是使用到代码级别,那应该是一个团队或者一个公司级别,换一个思路思考,那团队或者公司要求使用相同的架构和框架是不是也很合理?
关于第三个问题,实际上可以适当的选择Lombok的注解,对于不好用的注解可以选择不使用。在我看来,@Getter
和@Setter
就可以解决我大量的工作
关于第四个问题,实际上可以使用maven的配置就可以解决相关问题,可以增加true
,这样依赖可以不传给引用的项目。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。