java构造器和构建器

本文摘自:https://blog.csdn.net/wh2827991/article/details/79013115

在实例化一个类的过程中,通常会遇到多个参数的构造函数,但如果有些参数是非必需的呢?每次都要初始化那么多参数么?

public class Person {
    private int id;//身份证号
    private String name;//姓名
    private int age;//年龄
    private boolean sex;//性别
    private String desc;//个人描述
    public Person(int id, String name, int age, boolean sex, String desc) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.desc = desc;
    }
}

或者像下面这样,创建一个必选参数的构造器,在创建几个可选参数的构造器?

    public Person(int id, String name) {//两个参数的
        this.id = id;
        this.name = name;
    }
 
    public Person(int id, String name, int age) {//三个参数的
        this.id = id;
        this.name = name;
        this.age = age;
    }
 
    public Person(int id, String name, int age, boolean sex) {//四个参数的
        this.id = id;
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

或setter方法?

JavaBean模式自身有严重的缺点,因为构造过程被分到几个调用中,在构造过程中Javabean可能处于不一致的状态,类无法仅仅通过检验构造器参数的有效性来保证一致性。JavaBean模式阻止了把类做成不可变的可能,这就需要程序员付出额外的努力确保线程安全 ---摘自Effective Java

那么我们该怎样用构建器来实现类的实例化而又不受制于构造函数限制呢?

public class Person {
    private final int id;//身份证号
    private final String name;//姓名
    private int age;//年龄
    private boolean sex;//性别
    private String desc;//个人描述
    private Person(Builder builder){
        this.id=builder.id;
        this.name=builder.name;
        this.age=builder.age;
        this.sex=builder.sex;
        this.desc=builder.desc;
    }
    public static class Builder{
        private final int id;
        private final String name;
        private int age;
        private boolean sex;
        private String desc;
        public Builder(int id, String name) {
            this.id = id;
            this.name = name;
        }
        public Builder age(int age){
            //年龄合法性检查
            if(age<0)throw new IllegalArgumentException();
            else this.age=age;
            return this;
        }
        public Builder sex(boolean sex){
            this.sex=sex;
            return this;
        }
        public Builder desc(String desc){
            this.desc=desc;
            return this;
        }
        public Person build(){
            return new Person(this);
        }
    }
 
    @Override
    public String toString() {
        return "id:"+this.id+" 姓名:"+this.name+" 年龄:"+this.age+" 性别:"+this.sex+" 描述:"+this.desc;
    }
}

我们在main函数中测试一下

    public static void main(String[] args) {
        Builder builder=new Person.Builder(123,"张三");
        Person person=builder.age(18).sex(false).desc("好好学习,天天向上").build();
        System.out.println(person.toString());
    }
 

用构建器创建的实例易于阅读和编写,较javaBean模式又更加安全,自然,每种方法都会有其优点和弊端,选择合适的使用场景,会让代码更加健壮易读。

原文地址:https://www.cnblogs.com/cq-yangzhou/p/10071284.html