对象的创建过程
当首次创建某个类的对象时(构造器可看作静态方法),或者类的静态方法/静态域被访问时,Java解释器会定位并加载类的.class文件,所有静态初始化动作都会执行,这个静态初始化动作只执行一次。
--------------------分割线---------------------
总结一下对象的创建过程,假设有一个名为Dog的类:
1,即使没有显式的使用static关键字,构造器实际上也是静态方法。因此当创建类型为Dog的对象,或者Dog类的静态方法/静态域首次被访问时,Java解释器查找类路径,定位Dog.class文件。
2,载入Dog.class(将会创建一个Class对象),有关静态初始化的动作全部执行。因此,静态初始化只在Class对象首次加载时候进行一次。
3,当用new Dog()创建对象时,将在堆上分配足够的存储空间。
4,此块存储空间被清空,所以所有的基本数据类型被设置为默认值,引用类型被置为null。
5,执行所有出现于字段定义处的初始化动作
6,执行构造器
普通初始化例子
根据下面代码写出输出结果
package com.patrick.bishi;
public class TestVar {
public static int k = 0;
public static TestVar t1 = new TestVar("t1");
public static TestVar t2 = new TestVar("t2");
public static int i = print("i");
public static int n = 99;
public int j = print("j");
{
print("构造");
}
static {
print("静态");
}
public TestVar(String str) {
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
++i;
++n;
}
public static int print(String str) {
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
++n;
return ++i;
}
public static void main(String[] args) {
TestVar t = new TestVar("init");
}
}
分析:
1,执行main函数时进行类的加载,此时静态数据被置为默认值k=0,t1=null,t2=null,i=0,n=0。
2,执行静态初始化语句与静态初始化块
-
k=0,
-
为了初始化t1开始执行非静态初始化语句与非静态初始化块
-
print("j")语句输出: 1:j i=0 n = 0;
此时k = 1,n=1,i =1, j = 1; -
print("构造")语句输出:2:构造 i = 1 n = 1
此时k = 2,n = 2,i = 2,j = 1; -
执行构造器输出 3:t1 i = 2 n = 2
此时k=3,n=3,i=3,j=1 -
初始化t2开始执行非静态初始化语句与非静态初始化块
-
print("j")语句输出: 4:j i=3 n = 3;
此时k = 4,n=4,i =4, j = 4; -
print("构造")语句输出:5:构造 i = 4 n = 4
此时k = 5,n = 5,i = 5,j = 4; -
执行构造器输出 6:t2 i = 5 n = 5
此时k=6,n=6,i=6,j=4 -
给i赋值print("i")输出 7:i i = 6 n =6
此时k=7,n=7,i=7 -
给n赋值此时n=99
-
执行静态块print("静态")输出8:静态 i = 7 n = 99
此时k=8 n =100 i = 8 -
执行main方法中的初始化执行非静态初始化语句与非静态初始化块
-
print("j")语句输出: 9:j i=8 n = 100;
此时k = 9,n=101,i =9, j = 9; -
print("构造")语句输出:10:构造 i = 9 n = 101
此时k = 10,n = 102,i = 10,j = 9; -
执行构造器输出 11:init i = 10 n = 102
此时k=11,n=103,i=11,j=9
****整体输出:****1:j i=0 n=0 2:构造 i=1 n=1 3:t1 i=2 n=2 4:j i=3 n=3 5:构造 i=4 n=4 6:t2 i=5 n=5 7:i i=6 n=6 8:静态 i=7 n=99 9:j i=8 n=100 10:构造 i=9 n=101 11:init i=10 n=102
父类子类初始化顺序
父类:
public class Person {
{
System.out.println("父类非静态块");
}
static {
System.out.println("父类静态块");
}
public Person() {
System.out.println("父类构造器");
}
}
子类:
public class Male extends Person{
{
System.out.println("子类非静态块");
}
static {
System.out.println("子类静态块");
}
public Male() {
System.out.println("子类构造器");
}
}
测试类:
public class Main {
public static void main(String [] args){
Person person = new Male();
}
}
输出结果:
父类静态块
子类静态块
父类非静态块
父类构造器
子类非静态块
子类构造器
网友评论