我不明白该计划是如何运作的

时间:2014-04-19 14:31:13

标签: java

在“思考java”一书中有一段代码:

class Bowl {
    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);
    Table() {
        System.out.println("Table()");
        bowl2.f1(1);
    }
    void f2(int marker) {
        System.out.println("f2(" + marker + ")");
    }
    static Bowl bowl2 = new Bowl(2);
}

class Cupboard {
    Bowl bowl3 = new Bowl(3);
    static Bowl bowl4 = new Bowl(4);
    Cupboard() {
        System.out.println("Cupboard()");
        bowl4.f1(2);
    }
    void f3(int marker) {
        System.out.println("f3(" + marker + ")");
    }
    static Bowl bowl5 = new Bowl(5);
}


public class StaticInitialization {
    public static void main(String[] args) {
        System.out.println("create new object Cupboard() inside main");
        new Cupboard();
        System.out.println("create new object Cupboard() inside main");
        new Cupboard();
        table.f2(1);
        cupboard.f3(1);
    }
    static Table table = new Table();
    static Cupboard cupboard = new Cupboard();
}

我有一些问题需要了解它的工作原理。例如,为什么行:

System.out.println("create new object Cupboard() inside main");

不是第一个?为什么碗碗3不是静止的?有什么关系?请解释一下,我将非常感激。

输出:

Bowl(1)
Bowl(2)
Table()
f1(1)
Bowl(4)
Bowl(5)
Bowl(3)
Cupboard()
f1(2)
create new object Cupboard() inside main
Bowl(3)
Cupboard()
f1(2)
create new object Cupboard() inside main
Bowl(3)
Cupboard()
f1(2)
f2(1)
f3(1)

4 个答案:

答案 0 :(得分:0)

我仍然坚持你必须更仔细地阅读这本书!谁想要回答更多细节?

  

Bowl允许您查看类的创建,Table和Cupboard具有静态   碗的成员分散在他们的班级定义中。请注意,Cupboard创建了一个   静态定义之前的非静态碗碗3。   从输出中,您可以看到只有在必要时才会发生静态初始化。如果你   不要创建一个Table对象,你永远不会引用Table.bowl1或Table.bowl2,静态   碗碗1和碗2将永远不会被创建。它们仅在第一个表时初始化   创建对象(或发生第一次静态访问)。之后,静态对象不是   重新初始化。   初始化顺序首先是静态,如果它们尚未被前一个初始化   对象创建,然后是非静态对象。你可以在中看到这方面的证据   输出。要执行main()(静态方法),必须使用静态初始化类   然后初始化它的静态字段表和橱柜,这将导致这些   要加载的类,因为它们都包含静态Bowlobjects,然后加载Bowl。   因此,在main()启动之前,会加载此特定程序中的所有类。这是   通常情况并非如此,因为在典型的程序中,您不会将所有内容链接在一起   通过静态,就像你在这个例子中所做的那样。

总结创建对象的过程,请考虑一个名为Dog的类:

  1. 即使它没有显式使用static关键字,实际上也是构造函数 静态方法。所以第一次创建一个Dog类型的对象,或者第一次创建一个 访问类Dog的静态方法或静态字段,Java解释器必须 找到Dog.class,通过类路径搜索它。
  2. 当Dog.class被加载(创建一个Class对象,稍后你会学到),所有 它的静态初始化程序运行。因此,静态初始化仅发生一次,如 第一次加载Class对象。
  3. 当你创建一个新的Dog()时,首先是Dog对象的构造过程 为堆上的Dog对象分配足够的存储空间。
  4. 此存储被擦除为零,自动设置该Dog中的所有基元 对象为默认值(数字为零,布尔值为 char)和null的引用。
  5. 执行在字段定义点发生的任何初始化。
  6. 构造函数已执行。正如您将在Reusing Classes章节中看到的那样,这可能会 实际上涉及相当多的活动,特别是涉及继承时。

答案 1 :(得分:0)

碗(int标记){    System.out.println(" Bowl(" + marker +")");}

是什么调用构造函数..在谷歌搜索更多。

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

是类的调用方法..

我建议你先拿一本关于java的好书来清除OOP的概念。 如果你盲目地去,你可能会提出更多问题..

答案 2 :(得分:0)

StaticInitialization课程内你有..

static Table table = new Table();
    static Cupboard cupboard = new Cupboard();

1-您正在静态创建Table对象。这将是要执行的第一行代码。

2- static Bowl bowl1 = new Bowl(1); 下一个lint将在table类中,另一个静态对象是创建Bowl类。

碗类中的

3- System.out.println("Bowl(" + marker + ")");将被执行,因此这是第一个在控制台中打印的Sysout。 首先创建静态对象,然后创建static方法的main方法。

答案 3 :(得分:0)

以下是执行main()类的StaticInitialization方法时会发生什么:

  1. 由于main()是该类的static方法,因此加载StaticInitialization类。反过来,它的所有static初始化程序都按照发生的顺序执行。
  2. 第一个static字段为Table。这会加载Table类。
  3. 然后执行static类的Table个字段。哪个加载Bowl类。没有static初始值设定项在那里执行。
  4. 现在,Bowl类中的new Bowl(1)new Bowl(2)执行了Table构造函数。这会产生前两个打印语句 - Bowl(1)Bowl(2)
  5. 此时,Table类已完全加载,其所有static初始化程序都已执行。现在,为Table()类中的new Table()执行了StaticInitialization构造函数。
  6. 接下来是构造函数中的下一个输出 - Table(),然后调用bowl2.f1(1);。哪个打印f1(1)
  7. 到此为止,static类的第一个StaticInitialization初始化程序已完成。现在轮到Cupboard了。
  8. 我想从这里你可以追踪程序是如何工作的。只需按照类的初始化方式,以及该类的哪些代码将作为初始化的一部分执行。

      

    为什么Bowl bowl3不是静态的?有什么关系?

    它有所不同。由于该字段不是static,因此在加载类Cupboard时不会执行该字段。这就是为什么您会在Bowl(4)之前看到来自Bowl(3)的输出。只有在创建该类的实例时,才会初始化非static字段。

    有关详细信息,您可以查看 - JLS §12.4 - Initialization of Classes and Interfaces.