[TOC]
In the development process , It's usually defined as a lot of JavaBean, And then through IDE To generate its properties 、getter、setter、equals、hashcode、toString Method , When you want to add an attribute or change an attribute , For example, naming 、 Type, etc , We need to regenerate these methods mentioned above . Such repetitive work is meaningless ,Lombok The annotations inside can easily solve these problems .
- Official address :https://projectlombok.org/
- github Address :https://github.com/rzwitserlo...
lombok Implementation principle : Mainly through the abstract syntax tree (AST), After compilation , Corresponding to the class with its annotation , Then the annotation compiler will automatically correspond to the annotations in the project lombok Annotation files in the syntax tree , And automatically compile the corresponding class to generate getter perhaps setter Method , To simplify the code
pom.xml add to lombok
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>@Getter @Setter annotation
This pair of notes is well understood by name , Used in front of member variables , It is equivalent to generating the corresponding get and set Method , You can also specify access modifiers for the generated methods , Of course , The default is public, Take a look at the simple example below :
// Rumenz.java
/**
* @className: Rumenz
* @description: TODO Class description
* @author: Entry station rumenz.com
* @date: 2021/12/9
**/
public class RumenzGetSet {
@Getter @Setter
private Integer id;
@Getter @Setter
private String name;
}
Equivalent to
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(" Entry station ");
return r.getId()+r.getName();
}
}
visithttp://127.0.0.1:8080/rumenz/indexreturn1 Entry station
@NonNull annotation
This annotation can be used in front of a member method or a constructor's parameter , A non null check about this parameter will be automatically generated , If the argument is null , Throw a null pointer exception , Take an example
public class RumenzNonNull {
@Getter @Setter @NonNull
private Integer id;
@Getter @Setter @NonNull
private String name;
}Equivalent to
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();
}visithttp://127.0.0.1:8080/rumenz/index1Report errorsjava.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 + '\'' +
'}';
}
}- Equivalent to
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(" Entry station ");
return r.toString();
}visithttp://127.0.0.1:8080/rumenz/index1returnRumenzToString{id=1, name=' Entry station '}
EqualsAndHashCode annotation
@EqualsAndHashCode
public class RumenzEqualsAndHashCode {
@Getter @Setter
private Integer id;
@Getter @Setter
private String name;
}Equivalent to
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(" Entry station ");
RumenzEqualsAndHashCode r2=new RumenzEqualsAndHashCode();
r2.setId(1);
r2.setName(" Entry station ");
if(r1.equals(r2)){
return " equal ";
}
return " It's not equal ";
}@Data annotation
- 1) Generate a parameterless constructor ;
- 2) Attribute set/get Method ;
- 3)equals(), hashCode(), toString(), canEqual() Method .
@Data(staticConstructor="of")
public class RumenzData {
private Integer id;
private String name;
}
// Equivalent to
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(" Entry station ");
String name = of.getName();
return name;
}@Cleanup annotation
This annotation is used before the variable , It can guarantee that the resources represented by this variable will be automatically closed , The default is to call resources close() Method , If there are other ways to close the resource , You can use @Cleanup(“methodName”) To specify the method to call , Let's take the input-output stream as an example :
@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 Instead of inputStream.close();
return new String(b);
}Equivalent to
@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 annotation
@NoArgsConstructor Use on class , It can provide a parameterless constructor
@NoArgsConstructor
public class RumenzNoArgsConstructor {
private Integer id;
private String name;
}Equivalent to
public class RumenzNoArgsConstructor {
private Integer id;
private String name;
public RumenzNoArgsConstructor() {
}
}@RequiredArgsConstructor annotation
Appoint final Property generation and construction method
@ToString
@RequiredArgsConstructor
public class RumenzRequiredArgsConstructor {
private Integer id;
private final String name;
}
// Equivalent to
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 annotation
All fields in the class generate a constructor with parameters .
@ToString
@AllArgsConstructor
public class RumenzAllArgsConstructor {
private Integer id;
private String name;
}
// Equivalent to
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 annotation
- 1) Parametric construction method ;
- 2) Just add @Value annotation , There are no other restrictions , Then the class properties will be compiled into final Of , So only get Method , But not set Method .
@ToString
@Value
public class RumenzValue {
private Integer id;
private String name;
}// Equivalent to
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 annotation
This annotation is used for methods , You can use the code in the method try-catch The sentences are wrapped up , Catch the exception and in catch of use Lombok.sneakyThrow(e) Throw an exception , have access to @SneakyThrows(Exception.class) Specifies which exception to throw , A very simple note , Just look at an example :
@SneakyThrows
@GetMapping("/index9")
public String index9() {
// Use @SneakyThrows You don't have to throw an exception explicitly
File file = ResourceUtils.getFile("classpath:application.properties");
@Cleanup InputStream inputStream = new FileInputStream(file);
byte b[]=new byte[(int) file.length()];
inputStream.read(b);
//@Cleanup Instead of inputStream.close();
return new String(b);
}// Equivalent to
@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 annotation
synchronized Is an important keyword in thread safety , It is a kind of synchronous lock , Mainly used to ensure that at the same time , Only one thread can execute a method or a block of code . In general use synchronized To lock the code block , Not the way , Because locking code blocks is more efficient .
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(" Entry station ");
}
}// Equivalent to
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(" Entry station ");
}
}
}
@Builder annotation
Used in class 、 Constructors 、 On the way , Provide you with complex builder APIs
@ToString
@Builder
public class RumenzBuilder {
private Integer id;
private String name;
}
// Equivalent to
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(" Entry station ").build();
return rb.toString();
}@SuperBuilder
When an entity class has an integration relationship , Need to use @SuperBuilder, Otherwise, it will be called .builder All will report wrong. .
@Builder The construction of parent class member properties is not supported ,@SuperBuilder The emergence of annotations , To solve this problem .
Use @Builder or @SuperBuilder When the annotation , Null parameter constructors are not created by default , If you have an additional need to use null or full parameter constructors , You need to add the following comments to both the subclass and the parent class :
The source code address of this summary :
- GitHub:https://github.com/mifunc/spr...
- Gitee:https://gitee.com/rumenz/spri...
- https://rumenz.com/rumenbiji/...
Introduce
- My blog https://rumenz.com/ ,
- My toolbox https://tooltt.com/
- WeChat official account :【 Entry station 】
- Focus on 【 Entry station 】 reply 【1001】 obtain linux Quick reference manual of common commands
- Focus on 【 Entry station 】 reply 【1003】 obtain LeetCode Answer key 【java Language implementation 】
- Focus on 【 Entry station 】 reply 【1004】 obtain Java Basic core summary
- Focus on 【 Entry station 】 reply 【1009】 obtain Alibaba Java Development Manual





