Java对象是如何创建的?

1.检查static关键字

如果有static关键字修饰,即该对象为一个静态对象,那么其会被优先加载到虚拟机中执行;

2.找到class

找到class后,会创建一个Class对象,其所有static模块都会执行,但是只在对象载入时执行一次

3.分配内存

此时,new关键字所修饰的类进程会在内存堆(Heap)中,为该类分配足够的内存空间

4.初始化

这时,被分配的内存空间会被清零,并将不同的变量类型初始化为默认值(一般为0)

5.执行构造器

最后执行构造器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//StaticInitialization.java
class Bowl{
Bowl(int maker){
System.out.println("Bowl("+maker+")");
}
void f(int maker){
System.out.println("f("+maker+")");
}
}
class Table{
static Bowl b1 = new Bowl(1);
Table(){
System.out.println("Table");
b2.f(1);
}
void f2(int maker){
System.out.println("f2("+maker+")");
}
static Bowl b2 = new Bowl(2);
}
class Cupboard{
Bowl b3 = new Bowl(3);
static Bowl b4 = new Bowl(4);
Cupboard(){
System.out.println("Cupboard()");
b4.f(2);
}
void f3(int maker){
System.out.println("f3("+maker+")");
}
static Bowl b5 = new Bowl(5);
}
class Desk{
int desk;
Desk(){
System.out.println("Desk()");
}
static Bowl b6 = new Bowl(6);
}
public class StaticInitialization {
public static void main(String[] args) {
System.out.println("Creating new Cupboard in main");
new Cupboard();
//t2,t3已经实现被实例化了
t2.f2(1);
t3.f3(1);
System.out.println(desk.desk);
}
//静态对象被优先加载
static Table t2 = new Table();
static Cupboard t3 = new Cupboard();
static Desk desk = new Desk();
}

这里解释一下:为什么主函数之外的代码先执行了?

Java编译时会从main()所在的类开始编译,然后main()外的对象实例化都是静态的,所以,其会被优先加载到虚拟机中执行,执行完毕后,在进入主函数。

如果主函数变成这样呢:

1
2
3
4
5
6
public class StaticInitialization {
public static void main(String[] args) {
System.out.println("Creating new Cupboard in main");
new Cupboard();
}
}

此时,main()函数外没有静态变量,所以直接进入主函数;

  1. 输出:Creating new Cupboard in main
  2. 实例化一个Cupboard()对象:
    1. 寻找名为Cupboard的class
    2. 先执行其中的static
    3. 再执行构造器