lombok的简单使用

1.Eclipse安装插件

0.可以用maven引入依赖之后用maven下载相关jar包

        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
            <scope>provided</scope>
        </dependency>

1.找到lombok-1.18.12.jar

java -jar ./lombok-1.18.12.jar

 2.选择Eclipse对应的安装位置之后安装

3.安装成功在eclipse目录会生成lombok.jar

同时eclipse.ini也会增加一行:

-javaagent:E:\Eclipse\eclipse-jee-mars-1-win32-x86_64\eclipse-jee-mars-1-win32-x86_64\eclipse\lombok.jar

4.重启eclipse即可

二、IDEA安装

打开Idea, 左上角菜单选择 ”File --> Settings", 在弹出的对话框中,左侧选择Plugins,搜索栏输入'lombok', 然后点击安装,如下图:

   安装完重启即可。

三、lombok简单使用

pom文件引入依赖:(注意其依赖范围是provided-编译(compile)时需要,测试(test)时也需要 ,运行时不需要,打包时不需要)

        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
            <scope>provided</scope>
        </dependency>

1.测试常用注解@Getter、@Setter、@EqualsAndHashCode、@ToString

package cn.qlq.lombok;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@EqualsAndHashCode
@ToString
public class User {

    private long id;

    private String username;

}

jd反编译后查看代码:

package cn.qlq.lombok;

public class User
{
  private long id;
  private String username;
  
  public String getUsername()
  {
    return this.username;
  }
  
  public long getId()
  {
    return this.id;
  }
  
  public void setUsername(String username)
  {
    this.username = username;
  }
  
  public void setId(long id)
  {
    this.id = id;
  }
  
  protected boolean canEqual(Object other)
  {
    return other instanceof User;
  }
  
  public int hashCode()
  {
    int PRIME = 59;int result = 1;long $id = getId();result = result * 59 + (int)($id ^ $id >>> 32);Object $username = getUsername();result = result * 59 + ($username == null ? 43 : $username.hashCode());return result;
  }
  
  public boolean equals(Object o)
  {
    if (o == this) {
      return true;
    }
    if (!(o instanceof User)) {
      return false;
    }
    User other = (User)o;
    if (!other.canEqual(this)) {
      return false;
    }
    if (getId() != other.getId()) {
      return false;
    }
    Object this$username = getUsername();Object other$username = other.getUsername();return this$username == null ? other$username == null : this$username.equals(other$username);
  }
  
  public String toString()
  {
    return "User(id=" + getId() + ", username=" + getUsername() + ")";
  }
}

2.@NoArgsConstructor 、@AllArgsConstructor分别用于无参构造和有参构造

package cn.qlq.lombok;

import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

@NoArgsConstructor // 无参构造
@AllArgsConstructor // 有参构造
public class User {

    private long id;

    private String username;

}

反编译查看代码:

package cn.qlq.lombok;

public class User
{
  private long id;
  private String username;
  
  public User() {}
  
  public User(long id, String username)
  {
    this.id = id;this.username = username;
  }
}

3.@Data 相当于@Getter、@Setter、@EqualsAndHashCode、@ToString

package cn.qlq.lombok;

import lombok.Data;

@Data
public class User {

    private long id;

    private String username;

}

反编译查看:

package cn.qlq.lombok;

public class User
{
  private long id;
  private String username;
  
  public String toString()
  {
    return "User(id=" + getId() + ", username=" + getUsername() + ")";
  }
  
  public int hashCode()
  {
    int PRIME = 59;int result = 1;long $id = getId();result = result * 59 + (int)($id ^ $id >>> 32);Object $username = getUsername();result = result * 59 + ($username == null ? 43 : $username.hashCode());return result;
  }
  
  protected boolean canEqual(Object other)
  {
    return other instanceof User;
  }
  
  public boolean equals(Object o)
  {
    if (o == this) {
      return true;
    }
    if (!(o instanceof User)) {
      return false;
    }
    User other = (User)o;
    if (!other.canEqual(this)) {
      return false;
    }
    if (getId() != other.getId()) {
      return false;
    }
    Object this$username = getUsername();Object other$username = other.getUsername();return this$username == null ? other$username == null : this$username.equals(other$username);
  }
  
  public void setUsername(String username)
  {
    this.username = username;
  }
  
  public void setId(long id)
  {
    this.id = id;
  }
  
  public String getUsername()
  {
    return this.username;
  }
  
  public long getId()
  {
    return this.id;
  }
}

查看@Data源码如下:其实还有@RequiredArgsConstructor ,只是这个注解一般不用。

/** <a href="http://www.cpupk.com/decompiler">Eclipse Class Decompiler</a> plugin, Copyright (c) 2017 Chen Chao. */
package lombok;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Generates getters for all fields, a useful toString method, and hashCode and equals implementations that check
 * all non-transient fields. Will also generate setters for all non-final fields, as well as a constructor.
 * <p>
 * Equivalent to {@code @Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode}.
 * <p>
 * Complete documentation is found at <a href="https://projectlombok.org/features/Data">the project lombok features page for &#64;Data</a>.
 * 
 * @see Getter
 * @see Setter
 * @see RequiredArgsConstructor
 * @see ToString
 * @see EqualsAndHashCode
 * @see lombok.Value
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface Data {
    /**
     * If you specify a static constructor name, then the generated constructor will be private, and
     * instead a static factory method is created that other classes can use to create instances.
     * We suggest the name: "of", like so:
     * 
     * <pre>
     *     public @Data(staticConstructor = "of") class Point { final int x, y; }
     * </pre>
     * 
     * Default: No static constructor, instead the normal constructor is public.
     * 
     * @return Name of static 'constructor' method to generate (blank = generate a normal constructor).
     */
    String staticConstructor() default "";
}

 

需要注意:@Data生成toString和equals、hashCode时不会选择父类的字段,如下:

父类:

package cn.qlq.lombok;

import java.io.Serializable;

import lombok.Data;

@Data
public abstract class AbstractSequenceEntity implements Serializable {

    private static final long serialVersionUID = 7304379208787774552L;

    protected Long id;
}

反编译查看:

package cn.qlq.lombok;

import java.io.Serializable;

public abstract class AbstractSequenceEntity
  implements Serializable
{
  private static final long serialVersionUID = 7304379208787774552L;
  protected Long id;
  
  public String toString()
  {
    return "AbstractSequenceEntity(id=" + getId() + ")";
  }
  
  public int hashCode()
  {
    int PRIME = 59;int result = 1;Object $id = getId();result = result * 59 + ($id == null ? 43 : $id.hashCode());return result;
  }
  
  protected boolean canEqual(Object other)
  {
    return other instanceof AbstractSequenceEntity;
  }
  
  public boolean equals(Object o)
  {
    if (o == this) {
      return true;
    }
    if (!(o instanceof AbstractSequenceEntity)) {
      return false;
    }
    AbstractSequenceEntity other = (AbstractSequenceEntity)o;
    if (!other.canEqual(this)) {
      return false;
    }
    Object this$id = getId();Object other$id = other.getId();return this$id == null ? other$id == null : this$id.equals(other$id);
  }
  
  public void setId(Long id)
  {
    this.id = id;
  }
  
  public Long getId()
  {
    return this.id;
  }
}

 

子类如下:

package cn.qlq.lombok;

import lombok.Data;

@Data
public class User extends AbstractSequenceEntity {

    private static final long serialVersionUID = 1487903039867324395L;

    private String username;

}

 

反编译查看:没有从父类继承的属性

package cn.qlq.lombok;

public class User
  extends AbstractSequenceEntity
{
  private static final long serialVersionUID = 1487903039867324395L;
  private String username;
  
  public String toString()
  {
    return "User(username=" + getUsername() + ")";
  }
  
  public int hashCode()
  {
    int PRIME = 59;int result = 1;Object $username = getUsername();result = result * 59 + ($username == null ? 43 : $username.hashCode());return result;
  }
  
  protected boolean canEqual(Object other)
  {
    return other instanceof User;
  }
  
  public boolean equals(Object o)
  {
    if (o == this) {
      return true;
    }
    if (!(o instanceof User)) {
      return false;
    }
    User other = (User)o;
    if (!other.canEqual(this)) {
      return false;
    }
    Object this$username = getUsername();Object other$username = other.getUsername();return this$username == null ? other$username == null : this$username.equals(other$username);
  }
  
  public void setUsername(String username)
  {
    this.username = username;
  }
  
  public String getUsername()
  {
    return this.username;
  }
}

 

解决办法:

package cn.qlq.lombok;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
// callSuper: 是否包含父类的属性
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class User extends AbstractSequenceEntity {

    private static final long serialVersionUID = 1487903039867324395L;

    private String username;

}

反编译查看:

package cn.qlq.lombok;

public class User
  extends AbstractSequenceEntity
{
  private static final long serialVersionUID = 1487903039867324395L;
  private String username;
  
  public String getUsername()
  {
    return this.username;
  }
  
  public void setUsername(String username)
  {
    this.username = username;
  }
  
  public String toString()
  {
    return "User(super=" + super.toString() + ", username=" + getUsername() + ")";
  }
  
  public boolean equals(Object o)
  {
    if (o == this) {
      return true;
    }
    if (!(o instanceof User)) {
      return false;
    }
    User other = (User)o;
    if (!other.canEqual(this)) {
      return false;
    }
    if (!super.equals(o)) {
      return false;
    }
    Object this$username = getUsername();Object other$username = other.getUsername();return this$username == null ? other$username == null : this$username.equals(other$username);
  }
  
  protected boolean canEqual(Object other)
  {
    return other instanceof User;
  }
  
  public int hashCode()
  {
    int PRIME = 59;int result = super.hashCode();Object $username = getUsername();result = result * 59 + ($username == null ? 43 : $username.hashCode());return result;
  }
}

 

4.@Slf4j可以整合日志

原来我们使用日志的方式如下:

package cn.qlq.lombok;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class User {

    private static final Logger log = LoggerFactory.getLogger(User.class);

}

 

注解方式如下:

package cn.qlq.lombok;

import lombok.extern.slf4j.Slf4j;
@Slf4j
public class User {


}

反编译查看:

package cn.qlq.lombok;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class User
{
  private static final Logger log = LoggerFactory.getLogger(User.class);
}

5.@Builder用于生成加个构造者模式

package cn.qlq.lombok;

import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class User  {

    private long id;
    
    private String username;

}

测试代码:

package cn.qlq.lombok;

public class Client {
    public static void main(String[] args) {
        // 两种方式创建Builder
        // UserBuilder builder = User.builder();
        User.UserBuilder userBuilder = new User.UserBuilder();
        User user = userBuilder.id(5).username("admin").build();
        System.out.println(user);
    }
}

结果:

User(id=5, username=admin)

反编译查看:(User$UserBuilder.class是内部类编译后生成的cass文件)

package cn.qlq.lombok;

public class User
{
  private long id;
  private String username;
  
  public String toString()
  {
    return "User(id=" + getId() + ", username=" + getUsername() + ")";
  }
  
  public int hashCode()
  {
    int PRIME = 59;int result = 1;long $id = getId();result = result * 59 + (int)($id ^ $id >>> 32);Object $username = getUsername();result = result * 59 + ($username == null ? 43 : $username.hashCode());return result;
  }
  
  protected boolean canEqual(Object other)
  {
    return other instanceof User;
  }
  
  public boolean equals(Object o)
  {
    if (o == this) {
      return true;
    }
    if (!(o instanceof User)) {
      return false;
    }
    User other = (User)o;
    if (!other.canEqual(this)) {
      return false;
    }
    if (getId() != other.getId()) {
      return false;
    }
    Object this$username = getUsername();Object other$username = other.getUsername();return this$username == null ? other$username == null : this$username.equals(other$username);
  }
  
  public void setUsername(String username)
  {
    this.username = username;
  }
  
  public void setId(long id)
  {
    this.id = id;
  }
  
  public String getUsername()
  {
    return this.username;
  }
  
  public long getId()
  {
    return this.id;
  }
  
  public static class UserBuilder
  {
    private long id;
    private String username;
    
    public String toString()
    {
      return "User.UserBuilder(id=" + this.id + ", username=" + this.username + ")";
    }
    
    public User build()
    {
      return new User(this.id, this.username);
    }
    
    public UserBuilder username(String username)
    {
      this.username = username;return this;
    }
    
    public UserBuilder id(long id)
    {
      this.id = id;return this;
    }
  }
  
  public static UserBuilder builder()
  {
    return new UserBuilder();
  }
  
  User(long id, String username)
  {
    this.id = id;this.username = username;
  }
}

 

package cn.qlq.lombok;

public class User$UserBuilder
{
  private long id;
  private String username;
  
  public String toString()
  {
    return "User.UserBuilder(id=" + this.id + ", username=" + this.username + ")";
  }
  
  public User build()
  {
    return new User(this.id, this.username);
  }
  
  public UserBuilder username(String username)
  {
    this.username = username;return this;
  }
  
  public UserBuilder id(long id)
  {
    this.id = id;return this;
  }
}

6. 注解 @Accessors  用于定义链式调用

1. 源码

package lombok.experimental;

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

@Target({ElementType.TYPE, ElementType.FIELD})
@Retention(RetentionPolicy.SOURCE)
public @interface Accessors {
    boolean fluent() default false;

    boolean chain() default false;

    String[] prefix() default {};
}

  解释:chain 用于setter 方法完成之后是否返回this, 也就是允许链式调用; fluent 为true 的情况下,setter 方法不带set、getter 方法不带get, 直接就是属性名称。比如:

@Data
@Accessors(fluent = true, chain = true)
public class User {

    private String username;

    private int age;
}

反编译查看生成的类信息:

package cn;

public class User {
    private String username;
    private int age;

    public User() {
    }

    public String username() {
        return this.username;
    }

    public int age() {
        return this.age;
    }

    public User username(final String username) {
        this.username = username;
        return this;
    }

    public User age(final int age) {
        this.age = age;
        return this;
    }

    public boolean equals(final 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 if (this.age() != other.age()) {
                return false;
            } else {
                Object this$username = this.username();
                Object other$username = other.username();
                if (this$username == null) {
                    if (other$username != null) {
                        return false;
                    }
                } else if (!this$username.equals(other$username)) {
                    return false;
                }

                return true;
            }
        }
    }

    protected boolean canEqual(final Object other) {
        return other instanceof User;
    }

    public int hashCode() {
        int PRIME = true;
        int result = 1;
        int result = result * 59 + this.age();
        Object $username = this.username();
        result = result * 59 + ($username == null ? 43 : $username.hashCode());
        return result;
    }

    public String toString() {
        String var10000 = this.username();
        return "User(username=" + var10000 + ", age=" + this.age() + ")";
    }
}

补充一些其他不常用的注解:

@Cleanup : 可以关闭流
@Synchronized : 加个同步锁

@SneakyThrows : 等同于try/catch 捕获异常

@NonNull : 如果给参数加个这个注解 参数为null会抛出空指针异常

@Value : 注解和@Data类似,区别在于它会把所有成员变量默认定义为private final修饰,并且不会生成set方法。

@RequiredArgsConstructor:相当于属性生成构造方法,在spring 上下文环境相当于构造注入。

补充:@SneakyThrows 的简单用法

  简单的说,它就是可以try。。catch。。。 然后向上抛异常。比如:

package qz;

import lombok.SneakyThrows;

import java.io.UnsupportedEncodingException;

public class Test {

    public static void main(String[] args) {
        test();

        test2();
    }

    // 常规写法
    private static void test() {
        try {
            String gg = new String("124".getBytes("ff"));
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    // 使用SneakyThrows 的写法
    @SneakyThrows
    private static void test2() {
        String gg = new String("124".getBytes("ff"));
    }

}

查看反编译后的class:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package qz;

import java.io.UnsupportedEncodingException;

public class Test {
    public Test() {
    }

    public static void main(String[] args) {
        test();
        test2();
    }

    private static void test() {
        try {
            new String("124".getBytes("ff"));
        } catch (UnsupportedEncodingException var1) {
            throw new RuntimeException(var1);
        }
    }

    private static void test2() {
        try {
            new String("124".getBytes("ff"));
        } catch (Throwable var1) {
            throw var1;
        }
    }
}

  主要看test2()方法,如果代码中直接这么写还编译不过去,lombok巧妙的骗过编译器,使其编译过去,不过多研究,简单记录会使用即可。

 

posted @ 2020-07-09 22:59  QiaoZhi  阅读(665)  评论(0编辑  收藏  举报