创建和销毁对象——遇到多个构造器参数时考虑使用构建器

参考资料:《Effective Java》、https://blog.csdn.net/zxd1435513775/article/details/83016670https://www.jianshu.com/p/e3832c06e32c

基础回顾

1.重叠构造器是什么?

当一个类中有很多成员变量,不同的变量组成不同功能的构造器。这时候就可以使用重叠构造器。

如下代码:

public class EJ01_02 {
    private String Name;
    private int Age;
    private double Height;
    private String Gender;
    private int Year;

    //这个构造器只需要Name、Age参数
    public EJ01_02(String Name,int Age){
        this.Name=Name;
        this.Age=Age;
    }

    //这个构造器只需要Name、Height参数
    public EJ01_02(String Name,double Height){
        this.Name=Name;
        this.Height=Height;
    }

    //这个构造器只需要Name、Height、Year参数
    public EJ01_02(String Name,String Gender,int Year){
        this.Name=Name;
        this.Gender=Gender;
        this.Year=Year;
    }
    //这个构造器需要所有参数
    public EJ01_02(String Name,int Age,double Height,String Gender,int Year){
        this.Name=Name;
        this.Age=Age;
        this.Height=Height;
        this.Gender=Gender;
        this.Year=Year;
    }
}

上面这段代码只有五个参数,而且还没写出所有组合就看上去有点多余。如果参数多起来,代码看上去可以说是非常糟糕。

而且组合多了后,一些类型相同的参数,如果顺序不对的话编译器并不会报错,但是运行时可能出现不可预估的错误。

下面要说到的构建器很好的解决了这个问题。

 

2.JavaBeans模式是什么?

当有多个可选的构造器参数除了上面的方法外,还有第二个方法,就是JavaBeans模式。

在这种模式下,先调用一个无参构造器来创建对象,然后调用setter方法来设置开发者需要用到的参数。

代码如下:

class JavaBeans_Demo {
    private String Name;
    private int Age;
    private double Height;
    private String Gender;
    private int Year;

    //无参构造器
    public JavaBeans_Demo(){ }
    
    //Setters
    public void setName(String val){Name=val;}
    public void setAge(int val){Age=val;}
    public void setHeight(double val){Height=val;}
    public void setGender(String val){Gender=val;}
    public void setYear(int val){Year=val;}
}
class EJ01_02_Test{
    public static void main(String args[]){
        //创建对象
        JavaBeans_Demo jb=new JavaBeans_Demo();
        //设置需要的参数
        jb.setName("张三");
        jb.setAge(18);
        jb.setGender("女");
    }
}

虽然上面的代码看上去比第一种更灵活,但是在构造过程中可能处于不一致的状态。

比如:两个线程同时对jb对象进行操作,可能A线程还没赋值完毕,B线程就开始获取属性,或者甚至两个线程的都进行赋值操作,后赋值的会覆盖前面的设置。

为了避免上面的情况发生,开发者还得确保它们的线程安全。

 

构建器——建造者(Builder)模式

首先看下面的代码:

class JavaBuilder_Demo {
    private String Name;
    private int Age;
    private double Height;
    private String Gender;
    private int Year;

    public JavaBuilder_Demo(Builder builder) {
        Name=builder.Name;
        Age=builder.Age;
        Height=builder.Height;
        Gender=builder.Gender;
        Year=builder.Year;
    }

    //静态内部类
    public static class Builder{
        private String Name;
        private int Age;
        private double Height;
        private String Gender;
        private int Year;

        public Builder name(String val){
            Name=val;
            return this;
        }
        public Builder age(int val){
            Age=val;
            return this;
        }
        public Builder height(double val){
            Height=val;
            return this;
        }
        public Builder Gender(String val){
            Gender=val;
            return this;
        }
        public Builder Year(int val){
            Year=val;
            return this;
        }

        public JavaBuilder_Demo build(){
            return new JavaBuilder_Demo(this);
        }
    }
}
class EJ01_02_Test2{
    public static void main(String args[]){
        //创建对象并在创建对象时就设置了参数,这样就不会出不一致的问题
        JavaBuilder_Demo jb=new JavaBuilder_Demo.Builder().name("张三").age(18).Gender("女").build();
    }
}

上面代码中,有几个要点:

1.需要写一个静态的内部类,在调用的时候,静态内部类里的构造器可以设置必须的参数。

2.return this的意思是返回实际调用这个方法的实例化对象。

3.为什么需要静态内部类,因为可以创建对象的时候就可以选择性的选择自己需要用到的属性,而不用在创建完对象后类似JavaBeans那样去设置属性值。

posted @ 2019-11-04 17:34  LingCode丶  阅读(245)  评论(0编辑  收藏  举报