Preface

What is lombok

The Lombok project is a Java library that is automatically inserted into editors and build tools. Lombok provides a set of useful comments to eliminate a lot of boilerplate code in Java classes.

Friends who are not familiar with lombok can read the official document and then read this article. The official documents are as follows

https://projectlombok.org/

text

Let's first look at a small example


Question: main function output?

Answer : Null pointer exception

Exception in thread "main" java.lang.NullPointerException
    at com.github.lybgeek.msg.test.User.addPositionList(User.java:25)
    at com.github.lybgeek.msg.test.User.main(User.java:30)

Friends who answered the correct answer, basically don’t need to read the following. Some friends may have questions. I clearly used it in my example.

  private List<String> positionList = new ArrayList<>();

Why would it report a null pointer?

The truth lies in the class file generated by lombok with @builder. Let’s see what the generated class file looks like after decompilation using @builder.


Everyone should see it at a glance when I see the red circle. It turns out that when we use

 User user = User.builder().username("张三").build();

At this time, the positionList in the user object will be overwritten by the positionList in the userBuilder, and the positionList in the userBuilder is null

How to solve

Method 1: add final modification in front of positionList
  private final List<String> positionList = new ArrayList<>();

At this time, @Budiler is used to generate class as

At this time, the positionList in the user object is still the original positionList, so there will be no null pointer exception

Method 2: Add @Builder.Default annotation in front of positionList
 @Builder.Default
 private List<String> positionList = new ArrayList<>();

At this time, @Budiler is used to generate class as

 public static class UserBuilder {
        private String username;
        private boolean positionList$set;
        private List<String> positionList;

        UserBuilder() {
        }

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

        public User.UserBuilder positionList(final List<String> positionList) {
            this.positionList = positionList;
            this.positionList$set = true;
            return this;
        }

        public User build() {
            List<String> positionList = this.positionList;
            if (!this.positionList$set) {
                positionList = User.$default$positionList();
            }

            return new User(this.username, positionList);
        }

When positionList$set is false, positionList of userBuilder will be assigned a value

User.$default$positionList();
即:
  private static List<String> $default$positionList() {
        return new ArrayList();
    }

Therefore, when the positionList in the user object is overwritten by the positionList in the userBuilder, and the positionList in the userBuilder is new ArrayList(), there will be no null pointer phenomenon at this time.

Method three: instantiate objects without building

Bundle

 User user = User.builder().username("张三").build();

Change to use

User user = new User();
 user.setUsername("张三");
 user.addPositionList("经理");

Summarize

Many times I don’t take it for granted


linyb极客之路
344 声望193 粉丝