[Turn] by lombok take you read through the builder Builder

The original address: https://www.jianshu.com/p/0d8fc3df3647?from=timeline&isappinstalled=0

A long time ago, I read Builder to build relevant content in the "effective java", but the actual development is not often used. Later in the project the lombok, found that it has an annotation "@Builder", it is to generate a builder for the java bean. Then, go back and review under the relevant knowledge, are summarized as follows.

1. lombok Use Case

// 创建名为Officer的java bean
@Builder
public class Officer { private final String id; private final String name; private final int age; private final String department; } // 调用构建器生成Officer实例 class BuilderTest { public static void main(String[] args) { Officer officer = Officer.builder().id("00001").name("simon qi") .age(26).department("departmentA").build(); } } 

2. decompile lombok generated Officer.class

Note: Please distinguish between two groups following terms: "builder methods" and "build method", "construction" and "builder."

public class Officer {
    private final String id; private final String name; private final int age; private final String department; Officer(String id, String name, int age, String department) { this.id = id; this.name = name; this.age = age; this.department = department; } public static Officer.OfficerBuilder builder() { return new Officer.OfficerBuilder(); } public static class OfficerBuilder { private String id; private String name; private int age; private String department; OfficerBuilder() { } public Officer.OfficerBuilder id(String id) { this.id = id; return this; } public Officer.OfficerBuilder name(String name) { this.name = name; return this; } public Officer.OfficerBuilder age(int age) { this.age = age; return this; } public Officer.OfficerBuilder department(String department) { this.department = department; return this; } public Officer build() { return new Officer(this.id, this.name, this.age, this.department); } public String toString() { return "Officer.OfficerBuilder(id=" + this.id + ", name=" + this.name + ", age=" + this.age + ", department=" + this.department + ")"; } } } 

We decompile Officer.class, get the source code above (with the best idea comes decompiler, jd-gui decompiled source code insufficiency).

We found the source code static inner classes of a OfficerBuilder, when we call the builder method actually returns an instance of this static inner classes. This OfficerBuilder class with the same Officer and member variables, and has a method named id, name, age and the department. These variables Officer as a member of the naming methods, member variables are to OfficerBuilder assignment and returns this.

These methods return this, in fact, return OfficerBuilder object calls these methods may also be referred to as "return the object itself." Call by returning the object itself, a method of forming a chain.

Look build method, which is a method of OfficerBuilder class. It creates a new Officer object and its member variable values passed to the member variables Officer. Therefore Officer officer = Officer.builder().id("00001").name("simon qi").age(26).department("departmentA").build();wording, equivalent to the following wording:

Officer.OfficerBuilder officerBuilder = new Officer.OfficerBuilder();
officerBuilder.id("00001").name("simon qi").age(26).department("departmentA"); Officer officer = officerBuilder.build(); 

So why this mode is called "builder" because you want to create an instance Officer class, you must first create an instance of the class OfficerBuilder. And this is OfficerBuilder builder, is a transition creates Officer object. So take advantage of this mode will create an intermediate instance, will increase the virtual machine memory consumption.

3. Only use @Builder annotated bug

We only use @Builder notes, I found lombok Officer for the generated class constructor is "default" (without the modifier add permissions, the default is "default" is).

The reason we use to build mode, the user is hoped to create an instance of the method provided by the builder. But "default" configuration, a class may be invoked in the same package (default limit calls of different classes package). So, we need this constructor is set to private. Then you need to use "@AllArgsConstructor (access = AccessLevel.PRIVATE)". Then we look at the constructor after the decompile:

private Officer(String id, String name, int age, String department) { this.id = id; this.name = name; this.age = age; this.department = department; } 

Therefore, the use lombok builder should "@Builder" and "@AllArgsConstructor (access = AccessLevel.PRIVATE)" combination, the final wording:

@Builder
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class Officer { private final String id; private final String name; private final int age; private final String department; } 

Construction mode 4. Why

If a class has a lot of member variables, we need to provide a constructor or a whole lot of set method argument. This allows the creation and assignment instance, become very cumbersome and not intuitive. We builder, allowing the assignment of variables become chained calls, and call the method name corresponds to the name of the member variable. Make creating and assigning objects have become very simple and intuitive.

5. Chain assignment method, be sure to use the builder model?

Not have to use to build mode, the reason for using the builder pattern, because we want to create an object is an object a member variable immutable.

You return to see Officer OfficerBuilder class and class, you will find that the class member variables Officer is final, and no member variables OfficerBuilder modified with final. Because the final modified member variable, you need to put down the value determined when the instance is created. However, when a large number of class member variables, we do not want the user to directly call the constructor's full participation.

So we used the middle class OfficerBuilder. This class chain in order to achieve the assignment, only the variable to non-final. No matter how you OfficerBuilder assignment instance, how to change, when you call the build method will return Officer instance a member variable immutable.

What if there is a lot of property, but it does not need to be a member variable immutable objects, we also need to builder model? The answer is, no, we can refer to the builder of the chain can change the code assignment:

public class Officer {
    private String id; private String name; private int age; private String department; public static Officer build() { return new Officer(); } private Officer() { } public Officer id(String id) { this.id = id; return this; } public Officer name(String name) { this.name = name; return this; } public Officer age(int age) { this.age = age; return this; } public Officer department(String department) { this.department = department; return this; } } 调用样式: Officer officer = Officer.build().id("00001").name("simon qi").age(26).department("departmentA"); 其实这时候构造器设为非private也行,写成private,只是为了调用build()显得更好看。 将构造器设为非private,可以写为如下形式: Officer officer = new Officer().id("00001").name("simon qi").age(26).department("departmentA"); 

So, I think when you use lombok of "@Builder" notes, or to think about. When you do not have a member variable immutable, you absolutely do not need to use builder mode, as this will consume memory java virtual machine.

6. Summary

So, I always recommend to learn knowledge, to learn to be in the project. Through the project, other than to explore the knowledge of the project is to enhance their shortcut. And knowledge can not be learned is dead, what knowledge is not online, we will only consider those knowledge points. We're going to think about some other people do not often think of the problem. For example, why should we do the middle class transition, so what is the purpose of writing yes.

The above knowledge to thoroughly understand, respond to interview builder when it handy. And by combat to answer questions, you are better able to demonstrate love to think of employees.

 

Guess you like

Origin www.cnblogs.com/gwyy/p/11203080.html