重读《Java编程思想》

相关最新代码已上传至我的GitHub了(https://github.com/WenyangSun/ThinkingInJava),后续例子没有在博客上更新。

1、在类的内部,变量定义的先后顺序决定了初始化的顺序。即使变量定义散布于方法定义之间,它们仍旧会在任何方法(包括构造器)被调用之前得到初始化。

package com.ietree.base.initialization;

// 在类的内部,变量定义的先后顺序决定了初始化的顺序。即使变量定义散布于方法定义之间,它们仍旧会在任何方法(包括构造器)被调用之前得到初始化。
class Window
{
    Window(int maker)
    {
        System.out.println("Window(" + maker + ")");
    }
}

class House
{
    House()
    {
        System.out.println("House()"); // 4
        w3 = new Window(33); // 5
    }

    Window w1 = new Window(1); // 1

    Window w2 = new Window(2); // 2

    void f()
    {
        System.out.println("f()"); // 7
        Window w4 = new Window(4); // 8
    }

    Window w3 = new Window(3); // 3
}

// output:
// Window(1)
// Window(2)
// Window(3)
// House()
// Window(33)
// f()
// Window(4)
public class OrderOfInitialization
{
    public static void main(String[] args)
    {
        House h = new House();
        h.f(); // 6
    }
}

2、初始化的顺序是先静态对象,而后是“非静态”对象,构造器可以看成是静态方法。

package com.ietree.base.staticintialization;

/**
 * 初始化的顺序是先静态对象,而后是“非静态”对象,构造器可以看成是静态方法。
 */
class Bowl
{
    public Bowl(int marker)
    {
        System.out.println("Bowl(" + marker + ")");
    }

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

class Table
{
    static Bowl bowl1 = new Bowl(1); //2

    public Table()
    {
        System.out.println("Table()"); //4
        bowl2.f1(1); //5
    }

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

    static Bowl bowl2 = new Bowl(2); //3
}

class Cupboard
{
    Bowl bowl3 = new Bowl(3); //9 //14 //18

    static Bowl bowl4 = new Bowl(4); //7

    public Cupboard()
    {
        System.out.println("Cupboard()");//10 //15  //19
        bowl4.f1(2);//11 //16 //20
    }

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

    static Bowl bowl5 = new Bowl(5); //8
}

//output:
//Bowl(1)
//Bowl(2)
//Table()
//f1(1)
//Bowl(4)
//Bowl(5)
//Bowl(3)
//Cupboard()
//f1(2)
//Creating new Cupboard() in main
//Bowl(3)
//Cupboard()
//f1(2)
//Creating new Cupboard() in main
//Bowl(3)
//Cupboard()
//f1(2)
//f2(1)
//f3(1)
public class StaticIntialization
{
    public static void main(String[] args)
    {
        System.out.println("Creating new Cupboard() in main");//12
        new Cupboard();//13
        System.out.println("Creating new Cupboard() in main");
        new Cupboard(); //17
        table.f2(1); //21
        cupboard.f3(1);//22
    }

    static Table table = new Table(); //1

    static Cupboard cupboard = new Cupboard(); //6
}

3、类的创建过程是从基类向外扩散的,所以基类在导出类构造器可以访问它之前,就已经完成了初始化。

package com.ietree.base.reuseclass.extendskey;

class Art
{
    Art()
    {
        System.out.println("Art constructor"); // 2
    }
}

class Drawing extends Art
{
    Drawing()
    {
        System.out.println("Drawing constructor"); // 3
    }
}

// output:
// Art constructor
// Drawing constructor
// Cartoon constructor
public class Cartoon extends Drawing
{
    public Cartoon()
    {
        System.out.println("Cartoon constructor"); // 4
    }

    public static void main(String[] args)
    {
        @SuppressWarnings("unused")
        Cartoon x = new Cartoon(); // 1
    }
}

4、如果Java的基类拥有某个已被多次重载的方法名称,那么在子类中重新定义该方法名称并不会屏蔽其在基类中的任何版本

package com.ietree.base.reuseclass.hide;

class Homer
{
    char doh(char c)
    {
        System.out.println("doh(char)");
        return 'd';
    }

    float doh(float f)
    {
        System.out.println("doh(float)");
        return 1.0f;
    }
}

class Milhouse
{
}

class Bart extends Homer
{
    void doh(Milhouse m)
    {
        System.out.println("doh(Milhouse)");
    }
}

public class Hide
{
    public static void main(String[] args)
    {
        Bart b = new Bart();
        b.doh(1);
        b.doh('x');
        b.doh(new Milhouse());
    }
}
// output:
// doh(float)
// doh(char)
// doh(Milhouse)

 

posted @ 2017-10-27 08:07  远近啊  阅读(401)  评论(0编辑  收藏  举报