天天看點

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