在“思考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)
答案 0 :(得分:0)
我仍然坚持你必须更仔细地阅读这本书!谁想要回答更多细节?
Bowl允许您查看类的创建,Table和Cupboard具有静态 碗的成员分散在他们的班级定义中。请注意,Cupboard创建了一个 静态定义之前的非静态碗碗3。 从输出中,您可以看到只有在必要时才会发生静态初始化。如果你 不要创建一个Table对象,你永远不会引用Table.bowl1或Table.bowl2,静态 碗碗1和碗2将永远不会被创建。它们仅在第一个表时初始化 创建对象(或发生第一次静态访问)。之后,静态对象不是 重新初始化。 初始化顺序首先是静态,如果它们尚未被前一个初始化 对象创建,然后是非静态对象。你可以在中看到这方面的证据 输出。要执行main()(静态方法),必须使用静态初始化类 然后初始化它的静态字段表和橱柜,这将导致这些 要加载的类,因为它们都包含静态Bowlobjects,然后加载Bowl。 因此,在main()启动之前,会加载此特定程序中的所有类。这是 通常情况并非如此,因为在典型的程序中,您不会将所有内容链接在一起 通过静态,就像你在这个例子中所做的那样。
总结创建对象的过程,请考虑一个名为Dog的类:
答案 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
方法时会发生什么:
main()
是该类的static
方法,因此加载StaticInitialization
类。反过来,它的所有static
初始化程序都按照发生的顺序执行。static
字段为Table
。这会加载Table
类。 static
类的Table
个字段。哪个加载Bowl
类。没有static
初始值设定项在那里执行。Bowl
类中的new Bowl(1)
和new Bowl(2)
执行了Table
构造函数。这会产生前两个打印语句 - Bowl(1)
和Bowl(2)
。Table
类已完全加载,其所有static
初始化程序都已执行。现在,为Table()
类中的new Table()
执行了StaticInitialization
构造函数。Table()
,然后调用bowl2.f1(1);
。哪个打印f1(1)
。 static
类的第一个StaticInitialization
初始化程序已完成。现在轮到Cupboard
了。 我想从这里你可以追踪程序是如何工作的。只需按照类的初始化方式,以及该类的哪些代码将作为初始化的一部分执行。
为什么
Bowl bowl3
不是静态的?有什么关系?
它有所不同。由于该字段不是static
,因此在加载类Cupboard
时不会执行该字段。这就是为什么您会在Bowl(4)
之前看到来自Bowl(3)
的输出。只有在创建该类的实例时,才会初始化非static
字段。
有关详细信息,您可以查看 - JLS §12.4 - Initialization of Classes and Interfaces.