先看两个例子:
例1:
public class test {
public static int a;
static
{
a = 1;
System.out.println("静态代码块中:a = "+a);
}
{
a = 2;
System.out.println("非静态代码块中:a = "+a);
}
public test(){
this("有参构造函数中:a="+test.a);
//a = 3;
System.out.println("在无参构造函数中:a = "+test.a);
}
public test(String s){
//a = 4;
/*System.out.println(s+a);*/
System.out.println(s);
}
public static void main(String []args) {
test t = null;
System.out.println("!!!!!!");
t = new test();
System.out.println("main函数中:a = "+test.a);
}
}
执行的结果是:
静态代码块中:a = 1
!!!!!!
非静态代码块中:a = 2
有参构造函数中:a=1
在无参构造函数中:a = 2
main函数中:a = 2
例1的结论:
静态代码块是在类加载时自动执行的,非静态代码块是在创建对象时自动执行的代码,不创建对象不执行该类的非静态代码块。且执行 顺序为静态代码块------非静态代码块----构造函数。
例2:
parent.java
public class parent{ public static int p; static { p = 1; System.out.println("父类静态代码块中:p = "+p); } { p = 2; System.out.println("父类非静态代码块中:p = "+p); } public parent(){ //a = 3; System.out.println("父类在无参构造函数中:p = "+p); } public parent(String s){ //a = 4; /*System.out.println(s+a);*/ System.out.println("父类在有参构造函数中:p = "+p); } }
test.java
public class test extends parent{
public static int a;
static
{
a = 1;
System.out.println("静态代码块中:a = "+a);
}
{
a = 2;
System.out.println("非静态代码块中:a = "+a);
}
public test(){
//a = 3;
System.out.println("在无参构造函数中:a = "+test.a);
}
public test(String s){
//a = 4;
/*System.out.println(s+a);*/
System.out.println("在有参构造函数中:a = "+test.a);
}
public static void float2int()
{
int a = (int)3.2;
int b = (int)3.9;
System.out.println("a = "+a+" b = "+b);
}
public static void main(String []args) {
System.out.println("hello");
test t = new test();
test t2 = new test("hello");
}
}
父类静态代码块中:p = 1
静态代码块中:a = 1
hello
父类非静态代码块中:p = 2
父类在无参构造函数中:p = 2
非静态代码块中:a = 2
在无参构造函数中:a = 2
父类非静态代码块中:p = 2
父类在无参构造函数中:p = 2
非静态代码块中:a = 2
在有参构造函数中:a = 2
例2的结论:
对象的初始化顺序:首先执行父类静态的内容,父类静态的内容执行完毕后,接着去执行子类的静态的内容(实例化对象前),实例化对象时,看父类有没有非静态代码块,如果有就执行父类的非静
态代码块,父类的非静态代码块执行完毕,接着执行父类的构造方法;父类的构造方法执行完毕之后,它接着去看子类有没有非静态代码块,如果有就执行子类的非静态代码块。子类的非静态代码块执
行完毕再去执行子类的构造方法。总之一句话,静态代码块内容先执行,接着执行父类非静态代码块和构造方法,然后执行子类非静态代码块和构造方法。
注意:子类的构造方法,不管这个构造方法带不带参数,默认的它都会先去寻找父类的不带参数的构造方法。如果父类没有不带参数的构造方法,那么子类必须用supper关键子来调用父类带参数的构造方
法,否则编译不能通过。