关于java:第十三节使用Lombok简化你的代码

9次阅读

共计 11197 个字符,预计需要花费 28 分钟才能阅读完成。

[TOC]

在开发过程中,通常都会定义大量的 JavaBean,而后通过 IDE 去产生其属性的结构器、getter、setter、equals、hashcode、toString 办法,当要减少属性或者对某个属性进行扭转时,比方命名、类型等,都须要从新去产生下面提到的这些办法。这样反复的劳动没有任何意义,Lombok 外面的注解能够轻松解决这些问题。

  • 官网地址:https://projectlombok.org/
  • github 地址:https://github.com/rzwitserlo…

lombok 实现的原理:次要是通过形象语法树(AST),在编译解决后,对应到有其注解的类,那么注解编译器就会主动去对应我的项目中的注解对应到在 lombok 语法树中的注解文件,并通过主动编译对应来产生对应类中的 getter 或者 setter 办法,达到简化代码的目标

pom.xml 增加 lombok

<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <optional>true</optional>
</dependency>

@Getter @Setter 注解

这一对注解从名字上就很好了解,用在成员变量后面,相当于为成员变量生成对应的 get 和 set 办法,同时还能够为生成的办法指定拜访修饰符,当然,默认为 public,间接来看上面的简略的例子:

// Rumenz.java
/**
 * @className: Rumenz
 * @description: TODO 类形容
 * @author: 入门小站 rumenz.com
 * @date: 2021/12/9
 **/
public class RumenzGetSet {
    @Getter @Setter
    private Integer id;
    @Getter @Setter
    private String name;

}
  • 等价于

    public class RumenzGetSet {
      private Integer id;
      private String name;
    
      public Integer getId() {return id;}
    
      public void setId(Integer id) {this.id = id;}
    
      public String getName() {return name;}
    
      public void setName(String name) {this.name = name;}
    }
    
@RestController
@RequestMapping("/rumenz")
public class RumenzController {@GetMapping("/index")
    public String index(){RumenzGetSet r=new RumenzGetSet();
        r.setId(1);
        r.setName("入门小站");

        return r.getId()+r.getName();
    }
}

拜访 http://127.0.0.1:8080/rumenz/index 返回 1 入门小站

@NonNull 注解

这个注解能够用在成员办法或者构造方法的参数后面,会主动产生一个对于此参数的非空查看,如果参数为空,则抛出一个空指针异样,举个例子来看看

public class RumenzNonNull {
    @Getter @Setter @NonNull
    private Integer id;
    @Getter @Setter @NonNull
    private String name;
}
  • 等价于

    public class RumenzNonNull {
      private Integer id;
      private String name;
    
      public Integer getId() {return id;}
    
      public void setId(Integer id) {if (id == null) throw new java.lang.NullPointerException("id");
          this.id = id;
      }
    
      public String getName() {return name;}
    
      public void setName(String name) {if (name == null) throw new java.lang.NullPointerException("name");
          this.name = name;
      }
    }
@GetMapping("/index1")
public String index1(){RumenzNonNull r=new RumenzNonNull();
    r.setId(1);
    r.setName(null);

    return r.getId()+r.getName();
}

拜访 http://127.0.0.1:8080/rumenz/index1 报错java.lang.NullPointerException: name is marked non-null but is null

@ToString

@ToString
public class RumenzToString {

    @Getter @Setter
    private Integer id;

    @Getter @Setter
    private String name;

    @Override
    public String toString() {
        return "RumenzToString{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}
  • 等价于
public class RumenzToString {

    private Integer id;

    private String name;


    public Integer getId() {return id;}

    public void setId(Integer id) {this.id = id;}

    public String getName() {return name;}

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

    @Override
    public String toString() {
        return "RumenzToString{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}
@GetMapping("/index2")
public String index2(){RumenzToString r=new RumenzToString();
     r.setId(1);
     r.setName("入门小站");
     return r.toString();}

拜访 http://127.0.0.1:8080/rumenz/index1 返回RumenzToString{id=1, name='入门小站'}

EqualsAndHashCode 注解

@EqualsAndHashCode
public class RumenzEqualsAndHashCode {

    @Getter @Setter
    private Integer id;
    @Getter @Setter
    private String name;

}
  • 等价于

    public class RumenzEqualsAndHashCode {
      private Integer id;
      private String name;
    
      public Integer getId() {return id;}
    
      public void setId(Integer id) {this.id = id;}
    
      public String getName() {return name;}
    
      public void setName(String name) {this.name = name;}
    
      @Override
      public boolean equals(Object o) {if (this == o) return true;
          if (!(o instanceof RumenzEqualsAndHashCode)) return false;
          RumenzEqualsAndHashCode that = (RumenzEqualsAndHashCode) o;
          return id.equals(that.id) &&
                  name.equals(that.name);
      }
    
    }
@GetMapping("/index3")
public String index3(){RumenzEqualsAndHashCode r1=new RumenzEqualsAndHashCode();
    r1.setId(1);
    r1.setName("入门小站");

    RumenzEqualsAndHashCode r2=new RumenzEqualsAndHashCode();
    r2.setId(1);
    r2.setName("入门小站");
    if(r1.equals(r2)){return "相等";}
    return "不相等";
}

@Data 注解

  • 1)生成无参构造方法;
  • 2)属性的 set/get 办法;
  • 3)equals(), hashCode(), toString(), canEqual()办法。
@Data(staticConstructor="of")
public class RumenzData {


    private Integer id;

    private String name;

}
// 等价于

public class RumenzData {
    private Integer id;
    private String name;

    private RumenzData() {}

    public static RumenzData of() {return new RumenzData();
    }

    public Integer getId() {return this.id;}

    public String getName() {return this.name;}

    public void setId(final Integer id) {this.id = id;}

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

    public boolean equals(final Object o) {if (o == this) {return true;} else if (!(o instanceof RumenzData)) {return false;} else {RumenzData other = (RumenzData)o;
            if (!other.canEqual(this)) {return false;} else {Object this$id = this.getId();
                Object other$id = other.getId();
                if (this$id == null) {if (other$id != null) {return false;}
                } else if (!this$id.equals(other$id)) {return false;}

                Object this$name = this.getName();
                Object other$name = other.getName();
                if (this$name == null) {if (other$name != null) {return false;}
                } else if (!this$name.equals(other$name)) {return false;}

                return true;
            }
        }
    }

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

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

    public String toString() {return "RumenzData(id=" + this.getId() + ", name=" + this.getName() + ")";
    }
}
@GetMapping("/index4")
public String index4(){RumenzData of = RumenzData.of();
   of.setName("入门小站");
   String name = of.getName();
   return name;
}

@Cleanup 注解

这个注解用在变量后面,能够保障此变量代表的资源会被主动敞开,默认是调用资源的 close()办法,如果该资源有其它敞开办法,可应用 @Cleanup(“methodName”)来指定要调用的办法,就用输入输出流来举个例子吧:

@GetMapping("/index5")
public String index5() throws IOException {File file = ResourceUtils.getFile("classpath:application.properties");
   @Cleanup  InputStream inputStream = new FileInputStream(file);

   byte b[]=new byte[(int) file.length()];
   inputStream.read(b);
   //@Cleanup 代替了 inputStream.close();
   return new String(b);
}

等价于

@GetMapping({"/index5"})
public String index5() throws IOException {File file = ResourceUtils.getFile("classpath:application.properties");
        FileInputStream inputStream = new FileInputStream(file);

        String var4;
        try {byte[] b = new byte[(int)file.length()];
            inputStream.read(b);
            var4 = new String(b);
        } finally {if (Collections.singletonList(inputStream).get(0) != null) {inputStream.close();
            }

        }

        return var4;
}

@NoArgsConstructor 注解

@NoArgsConstructor 在类上应用,它能够提供一个无参结构器

@NoArgsConstructor
public class RumenzNoArgsConstructor {
    private Integer id;
    private String name;
}

等价于


public class RumenzNoArgsConstructor {
    private Integer id;
    private String name;

    public RumenzNoArgsConstructor() {}
}

@RequiredArgsConstructor 注解

指定 final 的属性生成构造方法

@ToString
@RequiredArgsConstructor
public class RumenzRequiredArgsConstructor {
    private Integer id;
    private final String name;
}

// 等价于

public class RumenzRequiredArgsConstructor {
    private Integer id;
    private final String name; //final

    public String toString() {return "RumenzRequiredArgsConstructor(id=" + this.id + ", name=" + this.name + ")";
    }

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

@AllArgsConstructor 注解

类中所有的字段都生成一个有参的构造方法.

@ToString
@AllArgsConstructor
public class RumenzAllArgsConstructor {
    private  Integer id;
    private  String name;
}

// 等价于

public class RumenzAllArgsConstructor {
    private Integer id;
    private String name;

    public String toString() {return "RumenzAllArgsConstructor(id=" + this.id + ", name=" + this.name + ")";
    }

    public RumenzAllArgsConstructor(final Integer id, final String name) {
        this.id = id;
        this.name = name;
    }
}

@Value 注解

  • 1)有参构造方法;
  • 2)只增加 @Value 注解,没有其余限度,那么类属性会被编译成 final 的,因而只有 get 办法,而没有 set 办法。
@ToString
@Value
public class RumenzValue {
    private Integer id;
    private String name;
}

// 等价于

public final class RumenzValue {
    private final Integer id;
    private final String name;

    public RumenzValue(final Integer id, final String name) {
        this.id = id;
        this.name = name;
    }

    public Integer getId() {return this.id;}

    public String getName() {return this.name;}

    public boolean equals(final Object o) {if (o == this) {return true;} else if (!(o instanceof RumenzValue)) {return false;} else {RumenzValue other = (RumenzValue)o;
            Object this$id = this.getId();
            Object other$id = other.getId();
            if (this$id == null) {if (other$id != null) {return false;}
            } else if (!this$id.equals(other$id)) {return false;}

            Object this$name = this.getName();
            Object other$name = other.getName();
            if (this$name == null) {if (other$name != null) {return false;}
            } else if (!this$name.equals(other$name)) {return false;}

            return true;
        }
    }

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

    public String toString() {return "RumenzValue(id=" + this.getId() + ", name=" + this.getName() + ")";
    }
}

@SneakyThrows 注解

这个注解用在办法上,能够将办法中的代码用 try-catch 语句包裹起来,捕捉异样并在 catch 中用 Lombok.sneakyThrow(e)把异样抛出,能够应用 @SneakyThrows(Exception.class)的模式指定抛出哪种异样,很简略的注解,间接看个例子:


@SneakyThrows
@GetMapping("/index9")
public String index9() {

        // 应用 @SneakyThrows 就不必显式抛出异样了
        File file = ResourceUtils.getFile("classpath:application.properties");
        @Cleanup  InputStream inputStream = new FileInputStream(file);

        byte b[]=new byte[(int) file.length()];
        inputStream.read(b);
        //@Cleanup 代替了 inputStream.close();
        return new String(b);
}

// 等价于

@GetMapping({"/index9"})
public String index9() {
        try {File file = ResourceUtils.getFile("classpath:application.properties");
            FileInputStream inputStream = new FileInputStream(file);

            String var4;
            try {byte[] b = new byte[(int)file.length()];
                inputStream.read(b);
                var4 = new String(b);
            } finally {if (Collections.singletonList(inputStream).get(0) != null) {inputStream.close();
                }

            }

            return var4;
        } catch (Throwable var9) {throw var9;}
}

@Synchronized 注解

synchronized 是线程平安中一个重要的关键字,它是一种同步锁,次要用来保障在同一个时刻,只有一个线程能够执行某个办法或者某段代码块。个别应用 synchronized 去锁住代码块,而不是办法,因为锁住代码块效率更高。

public class RumenzSynchronized {private final Object readLock = new Object();

    @Synchronized
    public static void hello() {System.out.println("rumenz.com");
    }

    @Synchronized
    public int answerToLife() {return 110;}

    @Synchronized("readLock")
    public void foo() {System.out.println("入门小站");
    }
}

// 等价于

public class RumenzSynchronized {private static final Object $LOCK = new Object[0];
    private final Object $lock = new Object[0];
    private final Object readLock = new Object();

    public RumenzSynchronized() {}

    public static void hello() {synchronized($LOCK) {System.out.println("rumenz.com");
        }
    }

    public int answerToLife() {synchronized(this.$lock) {return 110;}
    }

    public void foo() {synchronized(this.readLock) {System.out.println("入门小站");
        }
    }
}

@Builder 注解

用在类、结构器、办法上,为你提供简单的 builder APIs

@ToString
@Builder
public class RumenzBuilder {
    private Integer id;
    private String name;
}

// 等价于

public class RumenzBuilder {
    private Integer id;
    private String name;

    RumenzBuilder(final Integer id, final String name) {
        this.id = id;
        this.name = name;
    }

    public static RumenzBuilder.RumenzBuilderBuilder builder() {return new RumenzBuilder.RumenzBuilderBuilder();
    }

    public String toString() {return "RumenzBuilder(id=" + this.id + ", name=" + this.name + ")";
    }

    public static class RumenzBuilderBuilder {
        private Integer id;
        private String name;

        RumenzBuilderBuilder() {}

        public RumenzBuilder.RumenzBuilderBuilder id(final Integer id) {
            this.id = id;
            return this;
        }

        public RumenzBuilder.RumenzBuilderBuilder name(final String name) {
            this.name = name;
            return this;
        }

        public RumenzBuilder build() {return new RumenzBuilder(this.id, this.name);
        }

        public String toString() {return "RumenzBuilder.RumenzBuilderBuilder(id=" + this.id + ", name=" + this.name + ")";
        }
    }
}
@GetMapping("/index11")
public String index11() {RumenzBuilder rb=RumenzBuilder.builder().id(1).name("入门小站").build();
    return rb.toString();}

@SuperBuilder

当实体类有集成关系时, 须要用 @SuperBuilder, 否则调用的.builder 都会报错.

@Builder 并不反对父类成员属性的结构,@SuperBuilder 注解的呈现,就是用来解决这个问题。

应用 @Builder 或 @SuperBuilder 注解时,不会默认创立空参构造函数,如果你有额定应用空参构造函数或全参构造函数的需要,须要在子类和父类都加上以下注解:

本小结源码地址:

  • GitHub:https://github.com/mifunc/spr…
  • Gitee:https://gitee.com/rumenz/spri…
  • https://rumenz.com/rumenbiji/…

介绍

  • 我的博客 https://rumenz.com/ ,
  • 我的工具箱 https://tooltt.com/
  • 微信公众号:【入门小站】

  • 关注【入门小站】回复【1001】获取 linux 常用命令速查手册
  • 关注【入门小站】回复【1003】获取 LeetCode 题解【java 语言实现】
  • 关注【入门小站】回复【1004】获取 Java 根底外围总结
  • 关注【入门小站】回复【1009】获取 阿里巴巴 Java 开发手册
正文完
 0