当 new 一个对象时,类里面代码块执行顺序是:
1.静态属性和静态块(在第一次创建对象,或者首次访问时执行,只执行一次,后续不再执行)
2.构造块 (每次创建对象都会在构造方法之前执行)
3.构造方法 (每次创建对象都会执行)
阅读以下代码:
public class Cat {
static int a;
static {
System.out.println("静态块 start");
System.out.println("a = " + a);
a = 5;
System.out.println("静态块 end \n");
}
{
System.out.println("构造块 start");
System.out.println("a = " + a);
a = 6;
System.out.println("构造块 end \n");
}
public Cat(int i) {
System.out.println("构造方法 new Cat(" + i + ")");
System.out.println("a = " + a);
System.out.println("构造方法 end \n");
}
public static void main(String[] args) {
Cat cat1 = new Cat(1);
System.out.println("---------------");
Cat cat2 = new Cat(2);
}
}
/*
静态块 start
a = 0
静态块 end
构造块 start
a = 5
构造块 end
构造方法 new Cat(1)
a = 6
构造方法 end
---------------
构造块 start
a = 6
构造块 end
构造方法 new Cat(2)
a = 6
构造方法 end
*/
1. 静态属性和静态块,首次创建对象时执行,后续再创建对象不再执行,只保留一份空间
注意点:
静态代码块不能直接访问非静态属性和方法,必须通过创建对象进行访问。
若静态块在静态属性之前,则在该块中不得直接使用属性。
可间接使用,但属性值为默认,如下代码:
public class Cat {
static {
Cat cat = new Cat();
}
static Cat cat = new Cat();
static double d = 1.0;
public Cat() {
System.out.println("cat = " + cat);
System.out.println("d = " + d);
}
public static void main(String[] args) {
Cat cat = new Cat();
}
}
/**输出数据如下:
* cat = null
* d = 0.0
* cat = null
* d = 0.0
* cat = com.wb.staticdemo.Cat@422ede
* d = 1.0
*/
2. 构造块在每次创建对象时都会被调用,并且构造块的执行顺序在构造方法之前。
若出现多个构造块,则按照出现的次序执行。
阅读一下代码:
public class Cat {
{
Cat Cat = new Cat();
}
public static void main(String[] args) {
Cat cat = new Cat();
}
}
/*
* Exception in thread "main" java.lang.StackOverflowError
* ..............
*/
注意:在构造块内不能 new 本类对象,不然会因递归创建对象造成堆栈溢出异常
3.构造方法
同样的,构造方法在每次创建对象时都会在构造块之后执行,所以也不能在构造方法内在创建本类对象
否则会因递归创建对象造成堆栈溢出异常
如以下代码:
public class Cat {
public Cat() {
Cat cat = new Cat();
}
public static void main(String[] args) {
Cat cat = new Cat();
}
}
/*
* Exception in thread "main" java.lang.StackOverflowError
* ..............
*/