[plugin] ~lombok

一、简述

Project Lombok is a powerful tool for the pragmatic developer. It provides a set of useful annotations for eliminating a tremendous amount of boilerplate code from your Java classes. In the best cases, a mere five characters can replace hundreds of lines of code. The result is Java classes that are clean, concise and easy to maintain. These benefits do come with a cost however. Using Project Lombok in an IntelliJ IDEA shop is simply not yet a viable option. There is a risk of breakage with IDE and JDK upgrades as well as controversy surrounding the goals and implementation of the project. What all this translates to is no different than what must be considered for any technology choice. There are always gains to be made and losses to be had. The question is simply whether or not Project Lombok can provide more value than cost for the project at hand. If nothing else, Project Lombok is sure to inject some new life into the discussion of language features that have withered on the vine thus far and that is a win from any perspective.
Lombok项目是开发人员的强大的工具。它提供了一组有用的注释,用于消除Java类中大量的样板代码。在最好的情况下,仅仅五个字符就可以替换数百行代码。使得Java类干净、简洁、易于维护。然而,这些好处是有代价的。在IntelliJ IDEA商店中使用Lombok项目是一个不可行的选择。在IDE和JDK的升级中存在破损的风险,以及围绕项目目标和实现的争议。所有这些转换的结果与任何技术选择都没有什么不同。总有收获,也有损失。问题是,Lombok项目能否提供比手头项目更大的价值。如果没有其他的事情,Lombok项目肯定会注入一些新的生命来讨论到目前为止在vine上已经凋零的语言特性,从任何角度来看这都是一种胜利。

二、使用限制

While Project Lombok does some dramatic things to make a developer’s life easier, it has its limitations. Browsing the issues list will quickly illuminate some of the current shortcomings, most of which are minor. One important problem is the inability to detect the constructors of a superclass. This means that if a superclass has no default constructor any subclasses cannot use the @Data annotation without explicitly writing a constructor to make use of the available superclass constructor. Since Project Lombok respects any methods that match the name of a method to be generated, the majority of its feature shortcomings can be overcome using this approach.
虽然Lombok项目可以让开发人员的生活更轻松一些,但它也有其局限性。浏览问题列表可以快速地说明当前的一些缺点,其中大部分是次要的。一个重要的问题是无法检测超类的构造函数。这意味着,如果超类没有默认构造函数,任何子类都不能使用@Data注释,而不需要显式地编写构造函数来使用可用的超类构造函数。由于项目Lombok尊重任何与生成方法名称相匹配的方法,因此它的大部分特性缺点都可以通过这种方法来克服。

三、益处与消耗

As with any technology choice, there are both positive and negative effects of using Project Lombok. Incorporating Lombok’s annotations in a project can greatly reduce the number of lines of boilerplate code that are either generated in the IDE or written by hand. This results in reduced maintenance overhead, fewer bugs and more readable classes.
与任何技术选择一样,使用项目Lombok也有积极的和负面的影响。将Lombok的注释合并到一个项目中,可以大大减少在IDE中生成的样板代码行数,或者手工编写的代码。这就减少了维护开销,减少了bug,提高了可读性。
That is not to say that there are not downsides to using Project Lombok annotations in your project. Project Lombok is largely aimed at filling gaps in the Java language. As such, there is the possibility that changes to the language will take place that preclude the use of Lombok’s annotations, such as the addition of first class property support. Additionally, when used in combination with annotation-based object-relational mapping (ORM) frameworks, the number of annotations on data classes can begin to get unwieldy. This is largely offset by the amount of code that is superseded by the Lombok annotations. However, those who shun the frequent use of annotations may choose to look the other way.
这并不是说在您的项目中使用项目Lombok注释没有缺点。Lombok项目的主要目的是填补Java语言的空白。因此,可能会发生更改语言的情况,从而排除使用Lombok的注释,例如添加第一级属性支持。此外,当与基于注释的对象关系映射(ORM)框架结合使用时,数据类上的注释数量可能开始变得

1.官网https://www.projectlombok.org/
2.官网 特性简介
3.lombok所有特性

四、使用教程和常用注解

1.使用教程


添加依赖

<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok-maven -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok-maven</artifactId>
    <version>1.16.18.0</version>
</dependency>

<repositories>
    <repository>
        <id>projectlombok.org</id>
        <url>http://projectlombok.org/mavenrepo</url>
    </repository>
</repositories>

安装插件 idea
file - settings - plugins - 搜索 ‘lombok’ install

2.常用注解

@Getter and @Setter

@NonNull

@ToString

@EqualsAndHashCode

@Data

@Cleanup

@Synchronized

@SneakyThrows

@NoArgsConstructor @RequiredArgsConstructor @AllArgsConstructor

更多lombok注解特性

@Getter and @Setter
The @Getter and @Setter annotations generate a getter and setter for a field, respectively. The getters generated correctly follow convention for boolean properties, resulting in an isFoo getter method name instead of getFoo for any boolean field foo. It should be noted that if the class to which the annotated field belongs contains a method of the same name as the getter or setter to be generated, regardless of parameter or return types, no corresponding method will be generated.
注解 @Getter 和 @Setter 为 一个字段各自生成 getter和 setter方法。生成的getter方法正确地遵循了布尔属性的约定,结果是一个isFoo getter方法名,而不是任何布尔字段foo的getFoo。应该注意的是,如果注释字段所属的类包含与要生成的getter或setter相同名称的方法,无论参数还是返回类型,都不会生成相应的方法。

Both the @Getter and @Setter annotations take an optional parameter to specify the access level for the generated method.
@Getter和@Setter注释都使用可选参数来指定生成方法的访问级别。 见 AccessLevel

Lombok annotated code:
lombok 注解代码

@Getter @Setter private boolean employed = true;
@Setter(AccessLevel.PROTECTED) private String name;
//or
@Getter
@Setter
private boolean employed = true;
@Setter(AccessLevel.PROTECTED) 
private String name;

Equivalent Java source code:
等价于如下代码

private boolean employed = true;
private String name;

public boolean isEmployed() {
    return employed;
}

public void setEmployed(final boolean employed) {
    this.employed = employed;
}

protected void setName(final String name) {
    this.name = name;
}

注:@Getter 和@Setter方法也可以注释在类上,将为类每个字段生成对应的Getter 和Setter方法,可以指定AccessLevel控制生成的方法的访问权限,默认访问权限public
@Getter源码

package lombok;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.SOURCE)
public @interface Getter {
    AccessLevel value() default AccessLevel.PUBLIC;

    Getter.AnyAnnotation[] onMethod() default {};

    boolean lazy() default false;

    /** @deprecated */
    @Deprecated
    @Retention(RetentionPolicy.SOURCE)
    @Target({})
    public @interface AnyAnnotation {
    }
}

AccessLevel 枚举意义


package lombok;

public enum AccessLevel {
    PUBLIC,//生成public方法
    MODULE,//?
    PROTECTED,//生成protected方法
    PACKAGE,//生成 默认无修饰符方法
    PRIVATE,//生成 private方法
    NONE;//不生成

    private AccessLevel() {
    }
}

@NonNull
The @NonNull annotation is used to indicate the need for a fast-fail null check on the corresponding member. When placed on a field for which Lombok is generating a setter method, a null check will be generated that will result in a NullPointerException should a null value be provided. Additionally, if Lombok is generating a constructor for the owning class then the field will be added to the constructor signature and the null check will be included in the generated constructor code.
@NonNull注释用于指示对对应成员的快速失败空检查的需求。当放置在一个字段中,而Lombok正在生成一个setter方法时,将生成一个空检查,如果提供空值,将导NPE。此外,如果Lombok为拥有的类生成构造函数,那么该字段将被添加到构造函数签名中,而null检查将包含在生成的构造函数代码中。

This annotation mirrors @NotNull and @NonNull annotations found in IntelliJ IDEA and FindBugs, among others. Lombok is annotation agnostic with regards to these variations on the theme. If Lombok comes across any member annotated with any annotation of the name @NotNull or @NonNull, it will honor it by generating the appropriate corresponding code. The authors of Project Lombok further comment that, in the event that annotation of this type is added to Java, then the Lombok version will be subject to removal.
这个注释反映了在IntelliJ IDEA和FindBugs中发现的@NotNull和@NonNull注释。对于主题的这些变体,Lombok是注释无关的。如果Lombok遇到任何带有名称@NotNull或@NonNull注释的成员,它将通过生成相应的相应代码来表示对它的尊重。Lombok项目的作者进一步评论说,如果将该类型的注释添加到Java中,那么Lombok版本将会被删除。

Lombok annotated code from the class Family:


@Getter @Setter @NonNull
private List<Person> members;

Equivalent Java source code:

@NonNull
private List<Person> members;

public Family(@NonNull final List<Person> members) {
    if (members == null) throw new java.lang.NullPointerException("members");
    this.members = members;
}

@NonNull
public List<Person> getMembers() {
    return members;
}

public void setMembers(@NonNull final List<Person> members) {
    if (members == null) throw new java.lang.NullPointerException("members");
    this.members = members;
}
注意:可以注释在方法 ,参数,字段,局部变量上

@ToString
This annotation generates an implementation of the toString method. By default, any non-static fields will be included in the output of the method in name-value pairs. If desired, the inclusion of the property names in the output can be suppressed by setting the annotation parameter includeFieldNames to false.
该注释生成toString方法的实现。默认情况下,任何非静态字段将被包含在名称-值对的方法的输出中。如果需要,可以通过将注释参数includeFieldNames设置为false来抑制在输出中包含属性名。

Specific fields can be excluded from the output of the generated method by including their field names in the exclude parameter. Alternatively, the of parameter can be used to list only those fields which are desired in the output. The output of the toString method of a superclass can also be included by setting the callSuper parameter to true.
通过将其字段名包含在排除参数中,可以将特定字段排除在生成方法的输出之外。或者,可以使用参数只列出输出中需要的字段。超类的toString方法的输出也可以通过将callSuper参数设置为true来包含。

Lombok annotated code:

@ToString(callSuper=true,exclude="someExcludedField")
public class Foo extends Bar {
    private boolean someBoolean = true;
    private String someStringField;
    private float someExcludedField;
}

Equivalent Java source code:

public class Foo extends Bar {
    private boolean someBoolean = true;
    private String someStringField;
    private float someExcludedField;

    @java.lang.Override
    public java.lang.String toString() {
        return "Foo(super=" + super.toString() +
            ", someBoolean=" + someBoolean +
            ", someStringField=" + someStringField + ")";
    }
}

@ToString源码


package lombok;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.SOURCE)
public @interface ToString {
    boolean includeFieldNames() default true;//用来指定输出内容样式是否包含字段名 true: name=value false: value

    String[] exclude() default {};//用来指定被排除的字段

    String[] of() default {};//用来指定包含哪些字段 默认会包含所有非static 字段

    boolean callSuper() default false;//用来指定是否包含父类toString方法 默认不包含

    boolean doNotUseGetters() default false;//指定获取属性是否使用Getter方法,若为false 有getter则用,没有直接使用字段,若为true指定直接使用字段
}

@EqualsAndHashCode
This class level annotation will cause Lombok to generate both equals and hashCode methods, as the two are tied together intrinsically by the hashCode contract. By default, any field in the class that is not static or transient will be considered by both methods. Much like @ToString, the exclude parameter is provided to prevent field from being included in the generated logic. One can also use the of parameter to list only those fields should be considered.
这个类级别的注释将导致Lombok生成equals和hashCode方法,因为这两种方法本质上是由hashCode契约绑定在一起的。默认情况下,这两种方法都将考虑类中的任何非静态和transient的字段。很像@ToString,提供了排除参数,以防止字段被包含在生成的逻辑中。还可以使用参数列表只列出那些字段。

Also like @ToString, there is a callSuper parameter for this annotation. Setting it to true will cause equals to verify equality by calling the equals from the superclass before considering fields in the current class. For the hashCode method, it results in the incorporation of the results of the superclass’s hashCode in the calculation of the hash. When setting callSuper to true, be careful to make sure that the equals method in the parent class properly handles instance type checking. If the parent class checks that the class is of a specific type and not merely that the classes of the two objects are the same, this can result in undesired results. If the superclass is using a Lombok generated equals method, this is not an issue. However, other implementations may not handle this situation correctly. Also note that setting callSuper to true cannot be done when the class only extends Object, as it would result in an instance equality check that short-circuits the comparison of fields. This is due to the generated method calling the equals implementation on Object, which returns false if the two instances being compared are not the same instance. As a result, Lombok will generate a compile time error in this situation.

同@ToString,这个注释有一个callSuper参数。将其设置为true会导致等于通过在考虑当前类中的字段之前调用来自父类的equals来验证相等。对于hashCode方法,它会导致在计算散列时将超类的hashCode的结果合并在一起。在将callSuper设置为true时,要注意确保父类中的equals方法正确处理实例类型检查。如果父类检查类是特定类型的,而不仅仅是两个对象的类是相同的,这可能导致不理想的结果。如果超类使用的是Lombok生成的equals方法,这不是问题。但是,其他实现可能无法正确处理这种情况。还要注意,当类只扩展对象时,不能完成对true的设置,因为它会导致实例相等,检查字段的比较。这是因为生成的方法调用了对象上的equals实现,如果将两个实例进行比较,则返回false。因此,在这种情况下,Lombok将生成一个编译时错误。

Lombok annotated code:

@EqualsAndHashCode(callSuper=true,exclude={"address","city","state","zip"})
public class Person extends SentientBeing {
    enum Gender { Male, Female }

    @NonNull private String name;
    @NonNull private Gender gender;

    private String ssn;
    private String address;
    private String city;
    private String state;
    private String zip;
}

Equivalent Java source code:


public class Person extends SentientBeing {

    enum Gender {
        /*public static final*/ Male /* = new Gender() */,
        /*public static final*/ Female /* = new Gender() */;
    }
    @NonNull
    private String name;
    @NonNull
    private Gender gender;
    private String ssn;
    private String address;
    private String city;
    private String state;
    private String zip;

    @java.lang.Override
    public boolean equals(final java.lang.Object o) {
        if (o == this) return true;
        if (o == null) return false;
        if (o.getClass() != this.getClass()) return false;
        if (!super.equals(o)) return false;
        final Person other = (Person)o;
        if (this.name == null ? other.name != null : !this.name.equals(other.name)) return false;
        if (this.gender == null ? other.gender != null : !this.gender.equals(other.gender)) return false;
        if (this.ssn == null ? other.ssn != null : !this.ssn.equals(other.ssn)) return false;
        return true;
    }

    @java.lang.Override
    public int hashCode() {
        final int PRIME = 31;
        int result = 1;
        result = result * PRIME + super.hashCode();
        result = result * PRIME + (this.name == null ? 0 : this.name.hashCode());
        result = result * PRIME + (this.gender == null ? 0 : this.gender.hashCode());
        result = result * PRIME + (this.ssn == null ? 0 : this.ssn.hashCode());
        return result;
    }
}

@EqualsAndHashCode 源码


package lombok;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.SOURCE)
public @interface EqualsAndHashCode {
    String[] exclude() default {};//用来指定排除非唯一性字段

    String[] of() default {};//用来指定包含哪些唯一性字段

    boolean callSuper() default false;//是否包含父类EqualsAndHashCode方法

    boolean doNotUseGetters() default false;//用来指定获取字段是否通过getter方法

    EqualsAndHashCode.AnyAnnotation[] onParam() default {};

    /** @deprecated */
    @Deprecated
    @Retention(RetentionPolicy.SOURCE)
    @Target({})
    public @interface AnyAnnotation {
    }
}

@Data
The @Data annotation is likely the most frequently used annotation in the Project Lombok toolset. It combines the functionality of @ToString, @EqualsAndHashCode, @Getter and @Setter. Essentially, using @Data on a class is the same as annotating the class with a default @ToString and @EqualsAndHashCode as well as annotating each field with both @Getter and @Setter. Annotation a class with @Data also triggers Lombok’s constructor generation. This adds a public constructor that takes any @NonNull or final fields as parameters. This provides everything needed for a Plain Old Java Object (POJO).
@Data注释可能是项目Lombok工具集中最常用的注释。它结合了@ToString、@EqualsAndHashCode、@Getter和@Setter的功能。从本质上说,在类上使用@Data与使用默认@ToString和@EqualsAndHashCode的类进行注释,并使用@Getter和@Setter对每个字段进行注释。用@Data标注类也会触发Lombok的构造函数生成。这增加了一个公共构造函数,它将任何@NonNull或final字段作为参数。这为一个普通的旧Java对象(POJO)提供了所需的一切。

While @Data is extremely useful, it does not provide the same granularity of control as the other Lombok annotations. In order to override the default method generation behaviors, annotate the class, field or method with one of the other Lombok annotations and specify the necessary parameter values to achieve the desired effect.
虽然@Data非常有用,但它不提供与其他Lombok注释相同的控制粒度。为了覆盖默认的方法生成行为,使用另一个Lombok注释来注释类、字段或方法,并指定必要的参数值以达到预期的效果。

@Data does provide a single parameter option that can be used to generate a static factory method. Setting the value of the staticConstructor parameter to the desired method name will cause Lombok to make the generated constructor private and expose a static factory method of the given name.
@Data提供了一个单独的参数选项,可用于生成静态工厂方法。将staticConstructor参数的值设置为所需的方法名称将导致Lombok使生成的构造函数私有,并公开给定名称的静态工厂方法。

Lombok annotated code:

@Data(staticConstructor="of")
public class Company {
    private final Person founder;
    private String name;
    private List<Person> employees;
}

Equivalent Java source code:

public class Company {
    private final Person founder;
    private String name;
    private List<Person> employees;

    private Company(final Person founder) {
        this.founder = founder;
    }

    public static Company of(final Person founder) {
        return new Company(founder);
    }

    public Person getFounder() {
        return founder;
    }

    public String getName() {
        return name;
    }

    public void setName(final String name) {
        this.name = name;
    }

    public List<Person> getEmployees() {
        return employees;
    }

    public void setEmployees(final List<Person> employees) {
        this.employees = employees;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object o) {
        if (o == this) return true;
        if (o == null) return false;
        if (o.getClass() != this.getClass()) return false;
        final Company other = (Company)o;
        if (this.founder == null ? other.founder != null : !this.founder.equals(other.founder)) return false;
        if (this.name == null ? other.name != null : !this.name.equals(other.name)) return false;
        if (this.employees == null ? other.employees != null : !this.employees.equals(other.employees)) return false;
        return true;
    }

    @java.lang.Override
    public int hashCode() {
        final int PRIME = 31;
        int result = 1;
        result = result * PRIME + (this.founder == null ? 0 : this.founder.hashCode());
        result = result * PRIME + (this.name == null ? 0 : this.name.hashCode());
        result = result * PRIME + (this.employees == null ? 0 : this.employees.hashCode());
        return result;
    }

    @java.lang.Override
    public java.lang.String toString() {
        return "Company(founder=" + founder + ", name=" + name + ", employees=" + employees + ")";
    }
}

@Data源码


package lombok;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.SOURCE)
public @interface Data {
    String staticConstructor() default "";//若指定该字段,则构造器私有化,并提供给定名称的静态工厂方法
}

@Cleanup
The @Cleanup annotation can be used to ensure that allocated resources are released. When a local variable is annotated with @Cleanup, any subsequent code is wrapped in a try/finally block that guarantees that the cleanup method is called at the end of the current scope. By default @Cleanup assumes that the cleanup method is named “close”, as with input and output streams. However, a different method name can be provided to the annotation’s value parameter. Only cleanup methods which take no parameters are able to be used with this annotation.
可以使用@Cleanup注释来确保已分配的资源被释放。当用@Cleanup注释一个局部变量时,任何后续代码都被包装在try/finally块中,以确保在当前作用域结束时调用清理方法。默认情况下@Cleanup假定清理方法被命名为“close”,与输入和输出流一样。但是,可以向注释的值参数提供不同的方法名称。只有不带参数的清理方法才能使用这个注释。

There is also a caveat to consider when using the @Cleanup annotation. In the event that an exception is thrown by the cleanup method, it will preempt any exception that was thrown in the method body. This can result in the actual cause of an issue being buried and should be considered when choosing to use Project Lombok’s resource management. Furthermore, with automatic resource management on the horizon in Java 7, this particular annotation is likely to be relatively short-lived.
在使用@Cleanup注释时也需要考虑一下。如果清除方法抛出异常,则它将抢占方法主体中抛出的任何异常。这可能导致一个问题的实际原因被掩埋,在选择使用项目Lombok的资源管理时应该考虑。此外,在Java 7中,随着自动资源管理的出现,这个特殊的注释可能会相对短命的

Lombok annotated code:

public void testCleanUp() {
    try {
        @Cleanup ByteArrayOutputStream baos = new ByteArrayOutputStream();
        baos.write(new byte[] {'Y','e','s'});
        System.out.println(baos.toString());
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Equivalent Java source code:

public void testCleanUp() {
    try {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            baos.write(new byte[]{'Y', 'e', 's'});
            System.out.println(baos.toString());
        } finally {
            baos.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

@Synchronized
Using the synchronized keyword on a method can result in unfortunate effects, as any developer who has worked on multi-threaded software can attest. The synchronized keyword will lock on the current object (this) in the case of an instance method or on the class object for a static method. This means that there is the potential for code outside of the control of the developer to lock on the same object, resulting in a deadlock. It is generally advisable to instead lock explicitly on a separate object that is dedicated solely to that purpose and not exposed in such a way as to allow unsolicited locking. Project Lombok provides the @Synchronized annotation for that very purpose.
在方法上使用synchronized关键字会导致不幸的效果,因为任何开发多线程软件的开发人员都可以证明这一点。synchronized关键字将锁定在实例方法或静态方法的类对象上的当前对象(this)。这意味着,在开发人员的控制之外,有可能锁定同一个对象,从而导致死锁。通常建议将明确地锁定在一个单独的对象上,该对象只专注于该目的,而不以允许主动锁定的方式公开。Project Lombok为这个目的提供了@Synchronized注释。

Annotating an instance method with @Synchronized will prompt Lombok to generate a private locking field named lock on which the method will lock prior to executing. Similarly, annotating a static method in the same way will generate a private static object named LOCK for the static method to use in an identical fashion. A different locking object can be specified by providing a field name to the annotation’s value parameter. When a field name is provided, the developer must define the property as Lombok will not generate it.
使用@Synchronized注释一个实例方法将会提示Lombok生成一个名为lock的私有锁定字段,该方法将在执行之前锁定该方法。同样,以相同的方式注释静态方法将生成一个名为$LOCK的私有静态对象,用于以相同的方式使用静态方法。可以通过向注释的值参数提供字段名来指定不同的锁定对象。当提供字段名称时,开发人员必须定义该属性,因为Lombok将不会生成它。

Lombok annotated code:

private DateFormat format = new SimpleDateFormat("MM-dd-YYYY");

@Synchronized
public String synchronizedFormat(Date date) {
    return format.format(date);
}

Equivalent Java source code:

private final java.lang.Object $lock = new java.lang.Object[0];
private DateFormat format = new SimpleDateFormat("MM-dd-YYYY");

public String synchronizedFormat(Date date) {
    synchronized ($lock) {
        return format.format(date);
    }
}

@SneakyThrows

@SneakyThrows is probably the Project Lombok annotation with the most detractors, since it is a direct assault on checked exceptions. There is a lot of disagreement with regards to the use of checked exceptions, with a large number of developers holding that they are a failed experiment. These developers will love @SneakyThrows. Those developers on the other side of the checked/unchecked exception fence will most likely view this as hiding potential problems.

Throwing IllegalAccessException would normally generate an “Unhandled exception” error if IllegalAccessException, or some parent class, is not listed in a throws clause:

Screenshot of Eclipse generating an error message regarding unhandled exceptions.
When annotated with @SneakyThrows, the error goes away.

Screenshot of a method annotated with @SneakyThrows and generating no error in Eclipse.
By default, @SneakyThrows will allow any checked exception to be thrown without declaring in the throws clause. This can be limited to a particular set of exceptions by providing an array of throwable classes ( Class

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

Equivalent Java source code:

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

A look at the above code and the signature of Lombok.sneakyThrow(Throwable) would lead most to believe that the exception is being wrapped in a RuntimeException and re-thrown, however this is not the case. The sneakyThrow method will never return normally and will instead throw the provided throwable completely unaltered.

猜你喜欢

转载自blog.csdn.net/qq_37586182/article/details/78916367