public class InitObject {
private int id;
private String name;
private static int age;
public InitObject(){
System.out.println(id);
System.out.println(name);
System.out.println(age);
}
public static void main(String[] args) {
new InitObject();
}
}
输出结果:
0
null
0
从输出结果可以知道,一个类的所有成员变量无论是静态还是非静态的,都已经在调用构造方法之前被初始化过了。
public class StaticInitialization {
public static void main(String[] args) {
System.out.println("start");
new Market();
System.out.println("end");
}
static Shop shop = new Shop();
static Market market = new Market();
}
class Apple {
public Apple(int num) {
System.out.println("apple" + num);
}
}
class Shop {
Apple apple = new Apple(1);
static Apple apple2 = new Apple(2);
public Shop() {
System.out.println("shop");
}
}
class Market {
Apple apple = new Apple(1);
public Market() {
System.out.println("Market");
}
static Apple apple2 = new Apple(2);
}
输出结果:
apple2
apple1
shop
apple2
apple1
Market
start
apple1
Market
end
从输出结果可以看到静态数据只在必要时初始化,如果不创建Shop或者没有调用Shop中的静态方法或变 量,那么Shop中的静态数据永远也不会被初始化,
只有在第一个Shop对象被创建或者第一次访问静态数据的时候,静态成员变量才会被初始化,此后,无论静态对象不会再次被初始化。
初始化对象的顺序:先静态对象然后是非静态对象
下面以一道阿里巴巴的面试题来试试手
public class Alibaba {
public static int k = 0;
public static Alibaba t1 = new Alibaba("t1");
public static Alibaba t2 = new Alibaba("t2");
public static int i = print("i");
public static int n = 99;
private int a = 0;
public int j = print("j");
{
print("构造块");
}
static {
print("静态块");
}
public Alibaba(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[]) {
Alibaba t = new Alibaba("init");
}
}
根据初始化原则:有静态数据先初始化静态数据
k=0 t1=null t2=null i=0 n=0 又由于存在对静态数据的显示赋值: t1=new Alibaba("t1"); 这步之前会先初始类中的非静态的成员变量 所以会调用j=print("j"); 1:j i=0 n=0 由于存在构造块 2:构造块 i=1 n=1 然后调用构造方法 3:t1 i=2 n=2 接着初始化t2: 4:j i=3 n=3 5:构造块 i=4 n=4 6:t2 i=5 n=5 下一步为静态变量i赋值: 7:i i=6 n=6 接下来就是初始化静态块,然后是初始化非静态的成员变量然后执行构造块(如果有的话) 最后执行构造方法。