Java构建器

当创建对象需要传入多个参数的时候我们通常会根据参数的数量写不同的构造器,具体如下

public A(int a){}

public A(int a, int b){}

public A(int a, int b, int c){}

根据不同的参数调用不同的构造器,但是当参数多了的时候,这种方式不够灵活,所以会实现动态传参的方法

public A(){}

public void seta(int a){}

public void setb(int b){}

public void setc(int c){}

这种方式提高了传参的可读性,也提高了传参的灵活性,但是会增加代码行数,同时在多线程异步执行的时候导致奇怪的错误


有没有办法解决呢?既能提高代码可读性,提高参数灵活性,又不会增加代码行数,并保证线程安全呢?

构建器模式登场,先看代码:

public class A {

    private int a;

    private int b;

    private int c;


    public static class Builder {

        private int a;

        private int b;

        private int c;

        public Builder(){}

        public Builder seta(int a) { this.a = a; return this} 

        public Builder setb(int b) { this.b = b; return this}

        public Builder setc(int c) { this.c = c; return this}

        public A build() { return new A(this)}

    }


    private A(Builder builder) {

        this.a = builder.a;

        this.b = builder.b;

        this.c = builder.c;

    }

}


调用构造方法:

A a = new A.Builder().seta(1).setb(2).setc(3).build();


这样就解决了以上所说的问题,但是他的缺点同样也是存在的,就是:

1.构造器写起来很复杂

2.创建对象开销比较大

所以构建器模式只适用于需要传入很多种情况参数的时候,比如大于4种参数的配合,才比较划算。

而且值得注意的是:最好在类的设计之初就考虑是否使用构建器,否则日后扩展起来新构建器旧构造器一起用维护起来不方便。





初始化顺序首先是static(第一次初始化),其次是非static对象。

在对象建立的时候,对所有类static变量从上往下一次初始化,只发生一次。

其次是构建器初始化。

在new 对象()的时候,类中的所有变量都会被初始化

例子

class Cup {
Cup(int marker) {
System.out.println("Cup(" + marker + ")");
}
void f(int marker) {
System.out.println("f(" + marker + ")");
}
}


class Cups {
static Cup c1;
static Cup c2;
static {
c1 = new Cup(1);
c2 = new Cup(2);
}
Cups() {
System.out.println("Cups()");

}
}


public class ExplicitStatic {
public static void main(String[] args) {
System.out.println("Inside main()");
Cups.c1.f(99); // (1)
}
static Cups x = new Cups(); // (2)
static Cups y = new Cups(); // (2)

//Cups c = new Cups();(3)
} ///:~


输出

Cup(1)
Cup(2)
Cups()
Cups()
Inside main()
f(99)


若去掉(3的注释),也不会调用Cups c =new Cups();因为不是静态变量,也没有调用ExplicitStatic();

如果有extends

装载的时候会先去找父类,并载入,如果父类还有父类,会继续向上寻找父类,然后有上向下一个个载入,先static变量,再非static变量

所有必要类装载完毕后,会初始化所有成员变量,由父类开始先初始化成员变量,再构造器,再子类成员变量,构造器。

class Insect {
int i = 9;
int j;
Insect() {
prt("i = " + i + ", j = " + j);
j = 39;
}
static int x1 =
prt("static Insect.x1 initialized");
static int prt(String s) {
System.out.println(s);
return 47;
}
}

public class Beetle extends Insect {
int k = prt("Beetle.k initialized");
Beetle() {
prt("k = " + k);
prt("j = " + j);
}
static int x2 =
prt("static Beetle.x2 initialized");
static int prt(String s) {
System.out.println(s);
return 63;
}
public static void main(String[] args) {
prt("Beetle constructor");
Beetle b = new Beetle();
}
}

输出

static Insect.x initialized
static Beetle.x initialized
Beetle constructor
i = 9, j = 0
Beetle.k initialized
k = 63
j = 39

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值