Project Lombok

目录

干什么的

使用前

注解具体使用

@Getter和@Setter 替代get和set方法

@NonNull

@ToString

@EqualsAndHashCode

@Data

@Cleanup 默认value=close,用于关闭流等资源,就是try finally close,不建议使用

@Synchronized标注在方法上

@SneakyThrows

@NoArgsConstructor

@RequiredArgsConstructor

@AllArgsConstructor

@Builder

@SuperBuilder

日志相关

@Accessors


干什么的

使用注解的方式替代手动生成get/set、equal方法、日志引入等(减少样板式代码)

使用前

IDEA安装插件:Lombok Plugin

IDEA的market搜索不到解决方案解决IDEA中的lombok插件搜索不到的问题 - 程序员大本营https://www.pianshen.com/article/29191589451/

IDEA配置

        Settings设置页面,我们点击Build,Execution,Deployment-->选择Compiler-->选中Annotation Processors,然后在右侧勾选Enable annotation processing

pom配置

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.18</version>
    <!-- 编译阶段生效,不需要打入包中 -->
    <scope>provided</scope>
</dependency>

注解具体使用

@Getter和@Setter 替代get和set方法

  • 布尔类型的get方法类似是isFoo

  • 自己写了get/set方法,以自己写的为准

  • 标注在类上、方法上均可

  • 支持类似@Setter(AccessLevel.PROTECTED)指定访问权限

public enum AccessLevel {
	PUBLIC, MODULE, PROTECTED, PACKAGE, PRIVATE,
	/** Represents not generating anything or the complete lack of a method. */
	NONE;
}

@NonNull

  • lombok生成的set和构造器会检查是否为空,若提供空值,抛出NullPointerException
  • @Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE, ElementType.TYPE_USE})
{ElementType解释
    /** Class, interface (including annotation type), or enum declaration */
    TYPE,

    /** Field declaration (includes enum constants) */
    FIELD,

    /** Method declaration */
    METHOD,

    /** Formal parameter declaration */
    PARAMETER,

    /** Constructor declaration */
    CONSTRUCTOR,

    /** Local variable declaration */
    LOCAL_VARIABLE,

    /** Annotation type declaration */
    ANNOTATION_TYPE,

    /** Package declaration */
    PACKAGE,

    /**
     * Type parameter declaration
     *
     * @since 1.8
     */
    TYPE_PARAMETER,

    /**
     * Use of a type
     *
     * @since 1.8
     */
    TYPE_USE
}

@ToString

任何非静态字段都将以名称-值对的形式包含在方法的输出中。

  • callSuper 为true(默认false)时,调用父类的toString方法
  • includeFieldNames为true(默认) 包含字段名称
  • exclude,排除字段
  • of,包含字段
  • doNotUseGetters。为true是直接使用字段而不是调用get方法,默认false
  • onlyExplicitlyIncluded 为true时不输出任何字段信息,只输出了构造方法的名字,默认false

@EqualsAndHashCode

Lombok生成equals和hashCode方法

  • 与@ToString一样,此注释也有一个callSuper参数。将其设置为true将导致equals通过在考虑当前类中的字段之前从超类调用equals来验证相等性。对于hashCode方法,它会将超类的hashCode结果合并到哈希计算中。
  • 同样包含exclude、doNotUseGetters和of属性
  • 其他不懂得在这,希望懂得评论下
/**
	 * Determines how the result of the {@code hashCode} method will be cached.
	 * <strong>default: {@link CacheStrategy#NEVER}</strong>
	 *
	 * @return The {@code hashCode} cache strategy to be used.
	 */
	CacheStrategy cacheStrategy() default CacheStrategy.NEVER;
	
	/**
	 * Any annotations listed here are put on the generated parameter of {@code equals} and {@code canEqual}.
	 * This is useful to add for example a {@code Nullable} annotation.<br>
	 * The syntax for this feature depends on JDK version (nothing we can do about that; it's to work around javac bugs).<br>
	 * up to JDK7:<br>
	 *  {@code @EqualsAndHashCode(onParam=@__({@AnnotationsGoHere}))}<br>
	 * from JDK8:<br>
	 *  {@code @EqualsAndHashCode(onParam_={@AnnotationsGohere})} // note the underscore after {@code onParam}.
	 *  
	 * @return List of annotations to apply to the generated parameter in the {@code equals()} method.
	 */
	AnyAnnotation[] onParam() default {};

@Data

  • @ToString@EqualsAndHashCode@Getter, and @Setter合体而成
  • 在类上使用@Data与使用默认的@ToString和@EqualsAndHashCode注释该类以及使用@Getter和@Setter注释每个字段是一样的。用@Data注释类也会触发Lombok的构造函数生成。这将添加一个公共构造函数,该构造函数将任何@NonNull或final字段作为参数
  • staticConstructor属性,静态构造函数静态工厂方法,包含字段@NonNull或final字段
@Data(staticConstructor="of")
public class Company {

@Cleanup 默认value=close,用于关闭流等资源,就是try finally close,不建议使用

@Synchronized标注在方法上

使用 @Synchronized 注释实例方法将使该方法变为一个同步方法,生成一个名为$lock的私有锁定字段,该方法在执行之前会锁定该字段。类似地,以同样的方式注释静态方法将生成一个私有静态对象$LOCK,以便静态方法以相同的方式使用。可以通过向注释的值参数提供字段名来指定不同的锁定对象。当提供字段名时,开发人员必须确保Lombok不会生成该字段

@SneakyThrows

Skillythrow方法将永远不会正常返回,而是完全不变地抛出提供的可丢弃项。隐藏异常签名

使用

@SneakyThrows
public void testSneakyThrows() {
    throw new IllegalAccessException();
}

结果

public void testSneakyThrows() {
    try {
        throw new IllegalAccessException();
    } catch (java.lang.Throwable $ex) {
        throw lombok.Lombok.sneakyThrow($ex);
    }
}

@NoArgsConstructor

无参构造函数生成

  • force
    • 假如有final变量,则需指定参数force=true,不然编译报错
    • 使用无参数的构造函数构造出来的实例的成员变量值是 null,如果存在 @NonNull 修饰的成员字段,那么就矛盾了。所以如果有 @NonNull 修饰的成员变量就不要用 @NoArgsConstructor 修饰类了。(但是你这么做的话也不报错)
  • staticName
    • 如果设置该属性,则生成的构造函数将会变为私有的,另外还会生成一个静态“构造函数”。该静态函数内部会调用私有的构造函数
    • 如果该属性没有被指定值,则不起作用
  • access 访问权限,默认是public 
@NoArgsConstructor(staticName = "staticMethod", access = AccessLevel.PRIVATE, force = true)
public class UserInfo{

@RequiredArgsConstructor

  • 生成具有必需参数的构造函数。必需参数包括 final 修饰的字段和具有 @NonNull 注解的字段
  • 拥有staticName、access属性

@AllArgsConstructor

  • 生成参数包含类中所有字段的构造方法
  • 拥有staticName、access属性

@Builder

使用:

import lombok.Builder;

@Builder
public class UserInfo{
    private String userName;
    private Integer userAge;
}

生成代码

public class UserInfo {
    private String userName;
    private Integer userAge;
	
	//生成的全参数构造方法
    UserInfo(final String userName, final Integer userAge) {
        this.userName = userName;
        this.userAge = userAge;
    }

	//生成的静态工厂方法,用于构造内部类实例
    public static UserInfo.UserInfoBuilder builder() {
        return new UserInfo.UserInfoBuilder();
    }
	//生成的静态内部类
    public static class UserInfoBuilder {
        private String userName;
        private Integer userAge;

        UserInfoBuilder() {
        }

        public UserInfo.UserInfoBuilder userName(final String userName) {
            this.userName = userName;
            return this;
        }

        public UserInfo.UserInfoBuilder userAge(final Integer userAge) {
            this.userAge = userAge;
            return this;
        }
		//该方法用于返回外部类的完整实例
        public UserInfo build() {
            return new UserInfo(this.userName, this.userAge);
        }

        public String toString() {
            return "UserInfo.UserInfoBuilder(userName=" + this.userName + ", userAge=" + this.userAge + ")";
        }
    }
}

调用

UserInfo userInfo = UserInfo.builder().userName("zhangsan").userAge(14).build();
System.out.println(userInfo);
String str = UserInfo.builder().userName("zhangsan").userAge(14).toString();
System.out.println(str);
  • toBuilder
import lombok.Builder;
import lombok.ToString;

@ToString
@Builder(toBuilder = true)
public class UserInfo{
    private String userName;
    private Integer userAge;
}

多出来的方法

//toBuilder 属性生成的方法,用来生成新的实例
    public UserInfo.UserInfoBuilder toBuilder() {
        return (new UserInfo.UserInfoBuilder()).userName(this.userName).userAge(this.userAge);
    }

 调用

UserInfo userInfo = UserInfo.builder().userName("zhangsan").userAge(14).build();
System.out.println(userInfo);
//修改默写属性,并生成新对象
UserInfo userInfo1 = userInfo.toBuilder().userAge(34).build();
System.out.println(userInfo1);
  • access属性 指定访问权限
  • builderMethodName buildMethodName builderClassName替换名称

@SuperBuilder

  • 类似于 @Builder 注解,只在类上使用,主要用于有继承结构的情况下构建父类的参数。并且层次结构中的所有类都必须使用 @SuperBuilder 进行注释
  • 拥有属性toBuilder、builderMethodName、buildMethodName

日志相关

//@CommonsLog
private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(LogExample.class);

//@Flogger 谷歌的 FluentLogger 框架
private static final com.google.common.flogger.FluentLogger log = com.google.common.flogger.FluentLogger.forEnclosingClass();

//@JBossLog
private static final org.jboss.logging.Logger log = org.jboss.logging.Logger.getLogger(LogExample.class);

//@Log
private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName());

//@Log4j
private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LogExample.class);

//@Log4j2
private static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger(LogExample.class);

//@Slf4j Logback 框架
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class);

//@XSlf4j
private static final org.slf4j.ext.XLogger log = org.slf4j.ext.XLoggerFactory.getXLogger(LogExample.class);

//@CustomLog 自定义日志。@CustomLog 的主要目的是支持内部的、私有的日志框架。
private static final com.foo.your.Logger log = com.foo.your.LoggerFactory.createYourLogger(LogExample.class);

@Accessors

@Accessors 注解用来配置 Lombok 如何生成 getter 和 setter 方法,可以用在类上和字段上。单独使用这个注解是没有任何作用的,必须和一个可以生成 getter 和 setter 方法的注解一起使用,例如 @Setter、@Getter 或 @Data 注解

属性描述
fluent如果为 true 则生成的 getter/setter 方法没有 set/get 前缀,默认为 false。
如果该属性为 true,并且 chain 未设置,则 chain 会被默认设置为 true。
chain如果为 true 则生成的 setter 方法返回 this对象,默认为 false,生成的 setter 方法返回是 void。
如果没有显式设置该属性为 false,则当 fluent 为 true 时,chain 会被默认设置为 true。
prefix

该属性可以指定一系列前缀,生成 getter/setter 方法时会去掉指定的前缀。注意:
(1)只有字段中前缀的下一个字符不是小写字母或者前缀的最后一个字符不是字母(例如是下划线)时,前缀才算合法。
(2)如果去掉前缀时多个字段都变成相同的名称,将生成一个错误。

(3)如果设置的前缀不合法,会出现下面的警告,并且不会为该字段或该类的所有字段生成 getter/setter 方法。
Warning:(15, 21) java: Not generating getter for this field: It does not fit your @Accessors prefix list.
如果去掉前缀时多个字段都变成相同的名称,则只会给这几个字段中第一个字段(由上到下数)生成对

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值