watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

In fact, many people have answered this question , There are also a lot of little friends in Java One of the four masterpieces 《Effective Java》 No 1~5 I've learned about , However, I still want to sum up this issue with my own understanding , Talk about why we finally chose the builder to achieve our goal .

stay Java There are many ways to create objects in , To sum up, there are mainly the following 4 Ways of planting :

Normal creation : adopt new The operator

Reflection to create : call Class or java.lang.reflect.Constructor Of newInstance() Method

Cloning creates : Call the... Of an existing object clone() Method

Send serialization : call java.io.ObjectInputStream Of getObject() Method deserialization

Java Objects are created in such a way that their syntax specifies , Users cannot change from the outside . This article will still use the above method to create objects , So this article can only be said to build objects , Instead of creating an object .

Suppose there's a scenario like this , Now build a large object , This object contains many parameters , Some parameters are required , Some are optional . So how to build elegance 、 Building this object safely ?

1

01

Single constructor

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

Usually , The first thing we can think of is a single constructor . direct new The way to build , Passing parameters through constructors , See code below :

/***
*  Single constructor
*/
public class Person {
//  full name ( Required )
private String name;
//  Age ( Required )
private int age;
//  height ( optional )
private int height;
//  Graduation school ( optional )
private String school;
//  hobby ( optional )
private String hobby;
public Person(String name, int age, int height, String school, String hobby) {
this.name = name;
this.age = age;
this.height = height;
this.school = school;
this.hobby = hobby;
} }

The above construction method has the following disadvantages :

Some parameters are optional ( Such as height, school), In the build Person It is necessary to pass in parameters that may not be needed .

Now it's up there 5 Parameters , The constructor is already very long . If it is 20 Parameters , Constructors can go straight to heaven !

Building objects like this is very error prone .

The client has to compare Javadoc Or for the parameter name, the actual parameter is passed into the corresponding position . If the parameters are all String Type of , Once the wrong parameter is passed , Compilation is error free , But the result is wrong .

2

02

multiconstructor

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

For the first 1 A question , We can solve it by overloading constructors . See code below :

/***
*  multiconstructor
*/
public class Person {
//  full name ( Required )
private String name;
//  Age ( Required )
private int age;
//  height ( optional )
private int height;
//  Graduation school ( optional )
private String school;
//  hobby ( optional )
private String hobby;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person(String name, int age, int height) {
this.name = name;
this.age = age;
this.height = height;
}
public Person(String name, int age, int height, String school) {
this.name = name;
this.age = age;
this.height = height;
this.school = school;
}
public Person(String name, int age, String hobby, String school) {
this.name = name;
this.age = age;
this.hobby = hobby;
this.school = school;
} }

The above method can indeed reduce the length of the constructor to a certain extent , But it has the following defects :

Causes the class to be too long . This way will make Person Class's constructors grow in factorial order . In theory , The number of constructors that should be written is the number of combinations of optional member variables ( Not so much , For the reasons, see 2 spot ). If I call a class like this , Absolutely in my heart xx!!

Some parameter combinations cannot be refactored . because Java There are limits to overloading in , Methods signed by the same method cannot constitute overloads , Compile time cannot pass . For example, it includes (name, age, school) and (name, age, hobby) The constructor of cannot be overloaded , because shcool and hobby A fellow String type .Java Only recognize the type of variable , Whatever you mean by variables .( Look at the face of society )

3

03

JavaBean The way

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

The above method doesn't work , Don't worry ! And the magic weapon ——JavaBean. The construction of an object is accomplished through multiple methods . See the following code directly :

public class Person {
//  full name ( Required )
private String name;
//  Age ( Required )
private int age;
//  height ( optional )
private int height;
//  Graduation school ( optional )
private String school;
//  hobby ( optional )
private String hobby;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void setHeight(int height) {
this.height = height;
}
public void setSchool(String school) {
this.school = school;
}
public void setHobby(String hobby) {
this.hobby = hobby;
} }
The code for the client to use this object is as follows :
public class Client {
public static void main(String[] args) {
Person person = new Person("james", 12);
person.setHeight(170);
person.setHobby("reading");
person.setSchool("xxx university");
} }

It looks like a perfect solution Person The problem of object construction , It's very elegant and convenient to use . exactly , This is really a great way to build objects in a single threaded environment , But if it is in a multithreaded environment, it still has its fatal flaw . In a multithreaded environment , This object cannot be built safely , Because it's not immutable . once Person Objects are built , We can go through at any time setXXX() Method to change the internal state of an object . Suppose a thread is executing with Person Object related business methods , Another thread changes its internal state , This leads to an unintelligible result . Due to the irregularity of thread running , It makes it possible that the problem cannot be reproduced , This time really can only cry .( It's hard for programmers ...)

4

04

Builder The way

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

To solve this problem perfectly , The following leads to the protagonist of this article ( Etc., etc. !). We use the builder (Builder) To be elegant 、 Safely build Person object . Nonsense , Direct code :

/**
*  Objects to be built . The characteristics of the object :
* <ol>
* <li> You need to pass in multiple parameters manually , And there are several parameters that are optional 、 Random order </li>
* <li> The object is immutable ( The so-called immutability , It means that once the object is created , Its internal state is immutable ,
More generally, its member variables cannot be changed ).*  Immutable objects are thread safe in nature .</li>
* <li> The class to which the object belongs is not designed for inheritance .</li>
* </ol>
*  The construction of objects satisfying the above characteristics can use the following  Build  Way to build . There are some good things about building objects like this
It's about :
* <ol>
* <li> You don't need to write multiple constructors , Make the creation of objects more convenient </li>
* <li> The process of creating objects is thread safe </li>
* </ol>
* @author xiaoyu
* @date 2020-10-25
*/
public class Person {
//  full name ( Required ),final  modification  name  Once initialized, it cannot be changed , The immutability of the object is guaranteed
sex .
private final String name;
//  Age ( Required )
private final int age;
//  height ( optional )
private final int height;
//  Graduation school ( optional )
private final String school;
//  hobby ( optional )
private final String hobby;
/**
*  The function of this private constructor :
* <ol>
* <li> Initialization of member variables .final  Variables of type must be initialized , Otherwise, it will not compile successfully </li>
* <li> The private constructor ensures that the object cannot be created from outside , also  Person  Class cannot be inherited </li>
* </ol>
*/
private Person(String name, int age, int height, String school, String hobby) {
this.name = name;
this.age = age;
this.height = height;
this.school = school;
this.hobby = hobby;
}
/**
*  Action to perform
*/
public void doSomething() {
// TODO do what you want!!
}
/**
*  Builder . Why?  Builder  Is an internal static class ?
* <ol>
* <li> Must be  Person  The inner class of . otherwise , because  Person  The constructor of is private , Cannot pass  new  Of
Way to create  Person  object </li>
* <li> Must be a static class . because  Person  Object cannot be created from outside , If it's not a static class , Then there is no outside
Legal Citation  Builder  object .</li>
* </ol>
* <b> Be careful </b>:Builder  Internal member variables should be related to  Person  The member variables of are consistent .
* @author xiaoyu
*
*/
public static class Builder {
//  full name ( Required ). Be careful : It can't be  final  Of
private String name;
//  Age ( Required )
private int age;
//  height ( optional )
private int height;
//  Graduation school ( optional )
private String school;
//  hobby ( optional )
private String hobby;
public Builder(String name, int age) {
this.name = name;
this.age = age;
}
public Builder setHeight(int height) {
this.height = height;
return this;
}
public Builder setSchool(String school) {
this.school = school;
return this;
}
public Builder setHobby(String hobby) {
this.hobby = hobby;
return this;
}
/**
*  Building objects
* @return  Returns the object itself to be built
*/
public Person build() {
return new Person(name, age, height, school, hobby);
} } }

The way the client builds objects is shown in the following code :

/**
*  Use  Person  Object client
* @author xiaoyu
* @date 2020-10-25
*/
public class Client {
public static void main(String[] args) {
/*
*  Create... By chaining calls  Person  object , Very elegant !
*/
Person person = new Person.Builder("james", 12)
.setHeight(170)
.setHobby("reading")
.build();
person.doSomething();
} }

If you don't want to see the code , Here's a summary of the above code :

adopt private Person(..) bring Person Class cannot be inherited

By way of Person The member variable of the class is set to final type , Make it immutable

adopt Person Inside static Builder Class to build Person object

By way of Builder Intra class setXXX() Method returns Builder Type itself , Realize chain call construction Person Yes like

summary

thus , We can solve this type of object creation problem relatively perfectly ! Let's summarize the main points of this article . Characteristics of the object to be created :

You need to pass in multiple parameters manually , And there are several parameters that are optional 、 Any order

Object immutable

The class to which the object belongs is not designed for inheritance . That is, classes cannot be inherited

Object building methods used in turn :

Single constructor

multiconstructor

JavaBean The way

Builder The way

Final , By comparison, it is concluded that Builder The most appropriate solution is .

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

If you think that asamura's article will help you , Please search and follow on wechat 「 Shallow feathered IT hut 」 WeChat official account , I'll share my computer information knowledge here 、 Theoretical Technology 、 Tool resources 、 The software is introduced 、 The backend development 、 interview 、 A series of articles, such as thoughts on work and some thoughts on life . What you see and what you get , It's all about life . take your time , Work harder , You and I grew up together ...

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

I set up a technology group , If you want to know more about IT The technology of the industry and the problems in life , Welcome to join the group , Just add my wechat , Note that you can enter the group , We look forward to your participation .

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

Previous recommendation

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

More pictures , Understand 8 A common data structure


watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

High concurrency , Do you really understand ?


watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

dried food !MySQL Optimization principle analysis and optimization scheme summary


watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

hardcore !15 Zhang diagram Redis Why so soon?


watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

We media people's essential multi platform synchronization 、 More than one article


watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

Free working platform for programmers


watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

Programmer essential technology website Collection


watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

Things about image processing


watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

Shallow feather

Message area

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

Point a praise , Prove that you still love me