摘要:每个用的孩子都应该了解下主要依赖编译时代码生成技术,帮你自动生成基于模板的常用的代码,譬如最常见的与。另一种是通过类似于这样基于注解的在运行时利用反射动态添加,不过这样的缺陷是会影响性能,并且有一定局限性。
Lombok
每个用Java的孩子都应该了解下Lombok
Lombok主要依赖编译时代码生成技术,帮你自动生成基于模板的常用的Java代码,譬如最常见的Getter与Setter。之前动态的插入Getter与Setter主要有两种,一个是像Intellij与Eclipse这样在开发时动态插入,缺点是这样虽然不用你手动写,但是还是会让你的代码异常的冗长。另一种是通过类似于Spring这样基于注解的在运行时利用反射动态添加,不过这样的缺陷是会影响性能,并且有一定局限性。
Quick Start Installation文章的Github Repo
部分测试代码参考这里
笔者目前用的开发环境是Intellij+Gradle,这里只介绍下这种搭建方式,其他的基于Eclipse或者Maven的可以到官网主页查看。
(1)在Intellij中添加Plugin
Go to File > Settings > Plugins
Click on Browse repositories...
Search for Lombok Plugin
Click on Install plugin
Restart Android Studio
(2)允许注解处理
Settings -> Compiler -> Annotation Processors
(3)Gradle中添加依赖
compile "org.projectlombok:lombok:1.12.6"动态类型推导 Data Model:数据模型 Getter&Setter
源代码:
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); } }
编译之后的代码:
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; } }Lazy Getter
源代码:
import lombok.Getter; public class GetterLazyExample { @Getter(lazy=true) private final double[] cached = expensive(); private double[] expensive() { double[] result = new double[1000000]; for (int i = 0; i < result.length; i++) { result[i] = Math.asin(i); } return result; } }
编译之后:
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; } }Data
源代码:
import lombok.AccessLevel; import lombok.Setter; import lombok.Data; import lombok.ToString; @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{ private final String name; private final T value; } }
编译后:
import java.util.Arrays; public class DataExample { private final String name; private int age; private double score; private String[] tags; public DataExample(String name) { this.name = name; } public String getName() { return this.name; } void setAge(int age) { this.age = age; } public int getAge() { return this.age; } public void setScore(double score) { this.score = score; } public double getScore() { return this.score; } public String[] getTags() { return this.tags; } public void setTags(String[] tags) { this.tags = tags; } @Override public String toString() { return "DataExample(" + this.getName() + ", " + this.getAge() + ", " + this.getScore() + ", " + Arrays.deepToString(this.getTags()) + ")"; } protected boolean canEqual(Object other) { return other instanceof DataExample; } @Override public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof DataExample)) return false; DataExample other = (DataExample) o; if (!other.canEqual((Object)this)) return false; if (this.getName() == null ? other.getName() != null : !this.getName().equals(other.getName())) return false; if (this.getAge() != other.getAge()) return false; if (Double.compare(this.getScore(), other.getScore()) != 0) return false; if (!Arrays.deepEquals(this.getTags(), other.getTags())) return false; return true; } @Override public int hashCode() { final int PRIME = 59; int result = 1; final long temp1 = Double.doubleToLongBits(this.getScore()); result = (result*PRIME) + (this.getName() == null ? 43 : this.getName().hashCode()); result = (result*PRIME) + this.getAge(); result = (result*PRIME) + (int)(temp1 ^ (temp1 >>> 32)); result = (result*PRIME) + Arrays.deepHashCode(this.getTags()); return result; } public static class ExerciseObject Constructor{ private final String name; private final T value; private Exercise(String name, T value) { this.name = name; this.value = value; } public static Exercise of(String name, T value) { return new Exercise (name, value); } public String getName() { return this.name; } public T getValue() { return this.value; } @Override public String toString() { return "Exercise(name=" + this.getName() + ", value=" + this.getValue() + ")"; } protected boolean canEqual(Object other) { return other instanceof Exercise; } @Override public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof Exercise)) return false; Exercise> other = (Exercise>) o; if (!other.canEqual((Object)this)) return false; if (this.getName() == null ? other.getValue() != null : !this.getName().equals(other.getName())) return false; if (this.getValue() == null ? other.getValue() != null : !this.getValue().equals(other.getValue())) return false; return true; } @Override public int hashCode() { final int PRIME = 59; int result = 1; result = (result*PRIME) + (this.getName() == null ? 43 : this.getName().hashCode()); result = (result*PRIME) + (this.getValue() == null ? 43 : this.getValue().hashCode()); return result; } } }
源代码
import lombok.AccessLevel; import lombok.RequiredArgsConstructor; import lombok.AllArgsConstructor; import lombok.NonNull; @RequiredArgsConstructor(staticName = "of") @AllArgsConstructor(access = AccessLevel.PROTECTED) public class ConstructorExample{ private int x, y; @NonNull private T description; @NoArgsConstructor public static class NoArgsExample { @NonNull private String field; } }
编译之后:
public class ConstructorExampleBuilder{ private int x, y; @NonNull private T description; private ConstructorExample(T description) { if (description == null) throw new NullPointerException("description"); this.description = description; } public static ConstructorExample of(T description) { return new ConstructorExample (description); } @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; } public static class NoArgsExample { @NonNull private String field; public NoArgsExample() { } } }
源代码:
package wx.toolkits.basic.class_object.utils.lombok.object; import lombok.experimental.Builder; import java.util.Set; @Builder public class BuilderExample { private String name; private int age; private Setoccupations; public static void main(String args[]) { BuilderExample builderExample = BuilderExample.builder().build(); } }
编译之后的源代码:
import java.util.Set; public class BuilderExample { private String name; private int age; private SetException:异常处理 NonNulloccupations; BuilderExample(String name, int age, Set occupations) { this.name = name; this.age = age; this.occupations = occupations; } public static BuilderExampleBuilder builder() { return new BuilderExampleBuilder(); } public static class BuilderExampleBuilder { private String name; private int age; private java.util.ArrayList occupations; BuilderExampleBuilder() { } public BuilderExampleBuilder name(String name) { this.name = name; return this; } public BuilderExampleBuilder age(int age) { this.age = age; return this; } public BuilderExampleBuilder occupation(String occupation) { if (this.occupations == null) { this.occupations = new java.util.ArrayList (); } this.occupations.add(occupation); return this; } public BuilderExampleBuilder occupations(Collection extends String> occupations) { if (this.occupations == null) { this.occupations = new java.util.ArrayList (); } this.occupations.addAll(occupations); return this; } public BuilderExampleBuilder clearOccupations() { if (this.occupations != null) { this.occupations.clear(); } return this; } public BuilderExample build() { // complicated switch statement to produce a compact properly sized immutable set omitted. // go to https://projectlombok.org/features/Singular-snippet.html to see it. Set occupations = ...; return new BuilderExample(name, age, occupations); } @java.lang.Override public String toString() { return "BuilderExample.BuilderExampleBuilder(name = " + this.name + ", age = " + this.age + ", occupations = " + this.occupations + ")"; } } }
源代码:
import lombok.NonNull; public class NonNullExample extends Something { private String name; public NonNullExample(@NonNull Person person) { super("Hello"); this.name = person.getName(); } }
编译之后:
import lombok.NonNull; public class NonNullExample extends Something { private String name; public NonNullExample(@NonNull Person person) { super("Hello"); if (person == null) { throw new NullPointerException("person"); } this.name = person.getName(); } }SneakyThrows
源代码:
import lombok.SneakyThrows; public class SneakyThrowsExample implements Runnable { @SneakyThrows(UnsupportedEncodingException.class) public String utf8ToString(byte[] bytes) { return new String(bytes, "UTF-8"); } @SneakyThrows public void run() { throw new Throwable(); } }
编译之后:
import lombok.Lombok; public class SneakyThrowsExample implements Runnable { public String utf8ToString(byte[] bytes) { try { return new String(bytes, "UTF-8"); } catch (UnsupportedEncodingException e) { throw Lombok.sneakyThrow(e); } } public void run() { try { throw new Throwable(); } catch (Throwable t) { throw Lombok.sneakyThrow(t); } } }Thread:线程 Synchronized
源代码:
import lombok.Synchronized; public class SynchronizedExample { private final Object readLock = new Object(); @Synchronized public static void hello() { System.out.println("world"); } @Synchronized public int answerToLife() { return 42; } @Synchronized("readLock") public void foo() { System.out.println("bar"); } }
编译之后:
public class SynchronizedExample { private static final Object $LOCK = new Object[0]; private final Object $lock = new Object[0]; private final Object readLock = new Object(); public static void hello() { synchronized($LOCK) { System.out.println("world"); } } public int answerToLife() { synchronized($lock) { return 42; } } public void foo() { synchronized(readLock) { System.out.println("bar"); } } }Utils Cleanup
源代码:
import lombok.Cleanup; import java.io.*; 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); } } }
编译之后:
import java.io.*; 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(); } } } }Log:日志
使用@Log或者类似注解可以为类自动创建一个log对象,其效果如下所示:
@CommonsLog Creates private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(LogExample.class); @Log Creates private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName()); @Log4j Creates private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LogExample.class); @Log4j2 Creates private static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger(LogExample.class); @Slf4j Creates private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class); @XSlf4j Creates private static final org.slf4j.ext.XLogger log = org.slf4j.ext.XLoggerFactory.getXLogger(LogExample.class);
使用了Lombok之后的代码如下:
import lombok.extern.java.Log; import lombok.extern.slf4j.Slf4j; @Log public class LogExample { public static void main(String... args) { log.error("Something"s wrong here"); } } @Slf4j public class LogExampleOther { public static void main(String... args) { log.error("Something else is wrong here"); } } @CommonsLog(topic="CounterLog") public class LogExampleCategory { public static void main(String... args) { log.error("Calling the "CounterLog" with a message"); } }
编译之后的代码如下:
public class LogExample { private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName()); public static void main(String... args) { log.error("Something"s wrong here"); } } public class LogExampleOther { private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExampleOther.class); public static void main(String... args) { log.error("Something else is wrong here"); } } public class LogExampleCategory { private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog("CounterLog"); public static void main(String... args) { log.error("Calling the "CounterLog" with a message"); } }
其他可配置的参数为:
lombok.log.fieldName = an identifier (default: log)
The generated logger fieldname is by default "log", but you can change it to a different name with this setting.
lombok.log.fieldIsStatic = [true | false] (default: true)
Normally the generated logger is a static field. By setting this key to false, the generated field will be an instance field instead.
lombok.log.flagUsage = [warning | error] (default: not set)
Lombok will flag any usage of any of the various log annotations as a warning or error if configured.
lombok.log.apacheCommons.flagUsage = [warning | error] (default: not set)
Lombok will flag any usage of @lombok.extern.apachecommons.CommonsLog as a warning or error if configured.
lombok.log.javaUtilLogging.flagUsage = [warning | error] (default: not set)
Lombok will flag any usage of @lombok.extern.java.Log as a warning or error if configured.
lombok.log.log4j.flagUsage = [warning | error] (default: not set)
Lombok will flag any usage of @lombok.extern.log4j.Log4j as a warning or error if configured.
lombok.log.log4j2.flagUsage = [warning | error] (default: not set)
Lombok will flag any usage of @lombok.extern.log4j.Log4j2 as a warning or error if configured.
lombok.log.slf4j.flagUsage = [warning | error] (default: not set)
Lombok will flag any usage of @lombok.extern.slf4j.Slf4j as a warning or error if configured.
lombok.log.xslf4j.flagUsage = [warning | error] (default: not set)
Lombok will flag any usage of @lombok.extern.slf4j.XSlf4j as a warning or error if configured.
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/65956.html
摘要:使用方法能以简单的注解形式来简化代码,提高开发人员的开发效率。能通过注解的方式,在编译时自动为属性生成构造器方法。出现的神奇就是在源码中没有和方法,但是在编译生成的字节码文件中有和方法。没法实现多种参数构造器的重载。 1 Lombok背景介绍 官方介绍如下: Project Lombok makes java a spicier language by addi...
摘要:提高编码效率使代码更简洁消除冗长代码避免修改字段名字时忘记修改方法名提高下逼格以上就是的优点,当然,的优点远远不止以上几点,使用,你可以更加优雅高效的编辑代码。实战完成了上述准备之后,就可以愉快的使用进行编码了。接下来是使用简化后的代码。 Lombok介绍 近来偶遇一款撸码神器,介绍给大家~相信许多小伙伴都深有体会,POJO类中的千篇一律的getter/setter,construct...
摘要:不久前发现有一个第三方库可以在一定程度上帮助我们从体力劳动中解救出来,它就是。来看自动生成的方法中对于数组采用的是。检查传入对象是否为,若为,则抛出异常。比如自动抛受检异常,而无需显式在方法上使用语句。 前言 Laziness is a virtue!每当写pojo类时,都会重复写一些setter/getter/toString方法等大量的模版代码,无聊繁琐却又不得不做,这会让这个类变...
摘要:虽然有人可能会说里面都自带自动生成这些方法的功能,但是使用会使你的代码看起来更加简洁,写起来也更加方便。使用不使用自动生成方法使用不使用自动生成无参数构造函数。 一、lombok简介 lombok是在学习过程中发现的一个非常好用的小工具,用了之后感觉的确很不错,所以特此来推荐一下。 lombok的官方地址:https://projectlombok.org/ lombok的Github...
摘要:是一款在开发中简洁化代码十分有用的插件工具,使用注解,目的和作用就在于不用再去写经常反复去写的如,,等一些机械性代码了。也可以设置不包含哪些字段使用这个注解,就不用再去手写等方法了,注解后在编译时会自动加进去。 lombok是一款在java开发中简洁化代码十分有用的插件工具,使用lombok注解,目的和作用就在于不用再去写经常反复去写的(如Getter,Setter,Construct...
阅读 1364·2021-11-17 09:33
阅读 2940·2021-10-13 09:39
阅读 2623·2021-10-09 10:01
阅读 2419·2021-09-29 09:35
阅读 3854·2021-09-26 10:01
阅读 3492·2019-08-26 18:37
阅读 3124·2019-08-26 13:46
阅读 1887·2019-08-26 13:39