构造器初始化

  • A+
所属分类:编程茶楼


共计 2666 个字符,预计需要花费 7 分钟才能阅读完成。

《Thinking in Java》第五章中5.7小节“构造器初始化”;

/**
 * @author plm
 * @create 2021/2/17 18:18
 */
class House {
    private Window w1 = new Window(1);

    public House() {
        System.out.println("House : ()");
    }

    private Window w3 = new Window(3);

    void fun() {
        System.out.println("Have Fun.");
    }

    private Window w2 = new Window(2);
}

class Window {
    public Window(int num) {
        System.out.println("Window : (" + num + ")");
    }
}

public class OrderOfInitialization {
    public static void main(String[] args) {
        House house = new House();
        house.fun();
    }
}

/*
Window : (1)
Window : (3)
Window : (2)
House : ()
Have Fun.
*/

在类的内部,变量定义的先后顺序决定了初始化顺序,即使定义的位置在成员方法构造器的后面,也会最先得到初始化
Tips:在日常开发过程,我们不建议这么定义,不易维护与阅读。

static关键字不能应用于局部变量,因此它只能作用于域。

一个域是静态的基本类型域,并与也没有进行初始化,那么它就会获得基本类型的标准初始值
一个域是对象引用,name它的默认初始值就是null。

/**
 * @author plm
 * @create 2021/2/17 18:39
 */
public class StaticInitialization {
    public static void main(String[] args) {
        System.out.println("Step1.");
        new Home();
        System.out.println("Step2.");
        new Home();

        father.fun_1(1);

        home.fun_2(2);
    }

    static Father father = new Father();
    static Home home = new Home();
}

class Child {
    public Child(int marker) {
        System.out.println("Child : (" + marker + ")");
    }

    void fun(int marker) {
        System.out.println("fun : (" + marker + ")");
    }
}

class Father {
    static Child c1 = new Child(1);

    public Father() {
        System.out.println("Father()");
        c1.fun(1);
    }

    void fun_1(int marker) {
        System.out.println("fun_1 : (" + marker + ")");
    }

    static Child c2 = new Child(2);
}

class Home {
    Child c3 = new Child(3);

    static Child c4 = new Child(4);

    public Home() {
        System.out.println("Home()");
        c4.fun(2);
    }

    void fun_2(int marker) {
        System.out.println("fun_2 : (" + marker + ")");
    }

    static Child c5 = new Child(5);
}

/*
Child : (1)
Child : (2)
Father()
fun : (1)
Child : (4)
Child : (5)
Child : (3)
Home()
fun : (2)
Step1.
Child : (3)
Home()
fun : (2)
Step2.
Child : (3)
Home()
fun : (2)
fun_1 : (1)
fun_2 : (2)
*/

如上代码得出:执行main()方法(静态方法),必须加载StaticInitialization类,然后其静态域HomeFather被初始化,对应的类就要被加载,由于它们也包含静态域Child,所以Child也会被加载,这个是个特殊场景,所有的类都被static联系起来。

初始化的顺序:静态对象(如果它们尚未因前面的对象创建而未被初始化的话),“非静态”对象。
Tips:
1. 构造器也是静态方法,即使它没有显示的使用static关键字:因此当首次创建类时,或者该类的静态方法及静态域首次被访问时,就会加载该类;
2. 静态初始化只会在该类加载时进行一次
3. 为该类对象开辟内存空间
4. 该类对象的所有基本类型设置为默认值,引用类型设置为null
5. 再进行程序员自己定义的初始化动作:比如给某个字段赋初始值 private String a = "123";
6. 最后执行构造器

前者又称静态代码块,与其他静态初始化动作一样,只在类首次加载,或者首次访问该类的静态数据成员时,仅执行一次;

/**
 * @author plm
 * @create 2021/2/17 19:28
 */
public class ExplicitStatic {
    public static void main(String[] args) {
        System.out.println("Start.");
        new Cups();

        System.out.println("Step2.");
        new Cups();
    }
}

class Cups {
    static Cup c1;
    static Cup c2;
    Cup c3;
    Cup c4;

    static {
        c1 = new Cup(1);
        c2 = new Cup(2);
    }

    {
        c3 = new Cup(3);
        c4 = new Cup(4);
    }

    public Cups() {
         System.out.println("Cups init.");
    }
}

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

    void fun(int marker) {
        System.out.println("Fun : (" + marker + ")");
    }
}
/*
Start.
Cup : (1)
Cup : (2)
Cup : (3)
Cup : (4)
Cups init.
Step2.
Cup : (3)
Cup : (4)
Cups init.
*/

如上,注意观察非静态实例初始化,仅仅缺少了static关键字,每次调用构造器,它总是会发生,并且总先于构造方法执行。

  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的微信公众号
  • 我的微信公众号扫一扫
  • weinxin

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: