java程序初始化的执行顺序:按照静态域的顺序来执行。父类静态变量—>父类静态代码块—>子类静态变量—>子类静态代码块—>父类非静态变量—>父类非静态代码块(是代码块,而不是方法)—>父类构造方法—>子类非静态变量—>子类非静态代码块—>子类构造方法
1、构造块优先于构造方法执行,每产生一个新的对象就调用一次构造块
class Person{
{
System.out.println("1.Person类的构造块");
}
public Person(){
System.out.println("2.Person类的构造方法");
}
}
public class Test2 {
public static void main(String[] args) {
new Person();
new Person();
}
}
1.Person类的构造块
2.Person类的构造方法
1.Person类的构造块
2.Person类的构造方法
2、静态构造块
(1)静态块优先于构造块执行。
(2)无论产生多少实例化对象,静态块都只执行一次
- 非主类的静态块
例一:
class Person{
{
System.out.println("1.Person类的构造块");
}
public Person(){
System.out.println("2.Person类的构造方法");
}
static {
//定义在非主类的静态块
System.out.println("3.Person类的静态块");
}
}
public class Test2 {
public static void main(String[] args) {
System.out.println("--start--");
new Person();
new Person();
System.out.println("--end--");
}
}
--start--
3.Person类的静态块
1.Person类的构造块
2.Person类的构造方法
1.Person类的构造块
2.Person类的构造方法
--end--
例二:
public class T{
public static void main(String[] args) {
System.out.println("---start---");
new HelloB();
new HelloA();
System.out.println("---end---");
}
}
class HelloA {
//构造方法
public HelloA(){
System.out.println("Hello A!父类构造方法");
}
//非静态代码块
{
System.out.println("i'm A class.父类非静态代码块");
}
//静态代码块
static{
System.out.println("static A 父类静态代码块");
}
}
class HelloB extends HelloA {
//构造方法
public HelloB(){
System.out.println("Hello B! 构造方法");
}
//非静态代码块
{
System.out.println("i'm B class.非静态代码块");
}
//静态代码块
static{
System.out.println("static B 静态代码块");
}
}
---start---
static A 父类静态代码块
static B 静态代码块
i'm A class.父类非静态代码块
Hello A!父类构造方法
i'm B class.非静态代码块
Hello B! 构造方法
i'm A class.父类非静态代码块
Hello A!父类构造方法
---end---
- 在主类中的静态块
(1)在主类中定义的静态块,优先于主方法(main)执行
class HelloA {
//构造方法
public HelloA(){
System.out.println("Hello A!父类构造方法");
}
//非静态代码块
{
System.out.println("i'm A class.父类非静态代码块");
}
//静态代码块
static{
System.out.println("static A 父类静态代码块");
}
}
class HelloB extends HelloA {
//构造方法
public HelloB(){
System.out.println("Hello B! 构造方法");
}
//非静态代码块
{
System.out.println("i'm B class.非静态代码块");
}
//静态代码块
static{
System.out.println("static B 静态代码块");
}
public static void main(String[] args) {
System.out.println("---start---");
new HelloB();
new HelloA();
System.out.println("---end---");
}
}
static A 父类静态代码块
static B 静态代码块
---start---
i'm A class.父类非静态代码块
Hello A!父类构造方法
i'm B class.非静态代码块
Hello B! 构造方法
i'm A class.父类非静态代码块
Hello A!父类构造方法
---end---
例题解析:存在静态变量时的情况
public class Test4 {
public static Test4 main1 = new Test4();
public static Test4 main2 = new Test4();
{
System.out.println("构造块");
}
public Test4() {
System.out.println("构造方法");
}
static {
System.out.println("静态块");
}
public static void main(String[] args) {
Test4 main3 = new Test4();
}
}
构造块
构造方法
构造块
构造方法
静态块
构造块
构造方法
解析:在执行main之前先加载类,执行主类中的程序,加载类时并不会调用构造块和构造方法,只有静态域会执行,静态域中包含静态变量、静态块和静态方法,当执行到静态域时,按照静态域的顺序加载,并且静态块只在类的第一次加载时执行。执行静态域的第一个静态变量,输出构造块、构造方法,在执行第二个静态变量输出构造块、构造方法,最后执行静态块 ;静态块都已经初始化,所以main中不需要再执行静态块,直接执行构造块、构造方法。有些人会问为什么静态块不先执行呢?静态域是按照出现的顺序来执行的,一个执行完执行下一个。若静态块放在两个静态变量中间的时候,执行顺序为:构造块 构造方法 静态块 构造块 构造方法 构造块 构造方法
,