时间:2019/11/10
(1)静态代码块随着类的加载类的加载而执行,而且只执行一次
(2)在同一个类中,静态代码块的执行顺序优先于main函数
(3)继承中静态代码块的执行顺序
针对问题一,我们先看下面这段代码:
public class Main_Test{
public static void main(String[]args){
new One().lianxi();
new One().lianxi();
}
}
class One{
public void lianxi(){
System.out.println("函数被执行");
}
static{
System.out.println("静态代码块被执行);
}
}
结果为:
在上述代码中,我们创建了两个匿名的One对象,但是静态代码块只被执行了一次,而且在代码中,静态代码块写在lianxi函数的后面,但是执行的时候先执行的是静态代码块.
针对问题二,我们看下面这段代码:
public class Test_One{
static{
System.out.println("静态代码块被执行");
}
public static void main(String[] args){
System.out.println("main函数被执行");
}
}
运行结果为:
在上述代码中,main方法所在主类首先被加载,根据问题一中结论,主类被加载时会运行静态代码块,而且从运行结果中我们可以看出,静态代码块在执行时先于main方法执行.
针对问题三,我们来看一下下面这段代码:
public class Test_Three{
public static void main(String[] args){
new Two();
}
}
class One{
static{
System.out.println("父类中的静态代码块被执行");
}
public One(){
System.out.println("父类的构造方法被执行");
}
}
class Two extends One{
static{
System.out.println("子类中的静态代码块被执行");
}
public Two(){
//子类构造方法的第一行必须调用父类的构造方法,这里默认调用父类无参的构造方法
System.out.println("子类的构造方法被执行");
}
}
结果为
通过上述结果我们可以看出,当存在继承关系时,会先调用父类的静态代码块,然后调用子类的静态代码块,然后调用父类的构造方法,最后调用子类的构造方法.
(1)非静态代码块每创建一次对象就执行一次.
先看一下下面这段代码:
public class Test_Four{
{
System.out.println("非静态代码块被执行");
}
public static void main(String[] args){
System.out.prinltn("main函数被执行");
}
}
结果为:
再看一段代码:
public class Test_Four{
public static void main(String[] args){
System.out.println("main方法被调用");
new Five();
System.out.println("main方法被调用");
}
}
class Five{
{
System.out.println("静态代码块被执行");
}
public Five(){
System.out.println("构造方法被调用");
}
}
结果为:
对比两段代码的结果我们发现,非静态代码块不是在类加载时被调用的,而是在对象创建时被调用的,并且每创建一个对象就会被调用一次,即可以执行多次,而且执行的优先级要比静态代码块低很多,这从main方法的打印语句可以在非静态代码块之前被执行就可以看出来.
通过下面这段代码汇总一下静态代码块和非静态代码块的执行顺序:
package cn.machi12;
public class Test_Five extends Six{
static{
System.out.println("子类的静态代码块被调用");
}
{
System.out.println("子类的非静态代码块被调用");
}
public Test_Five(){
System.out.println("子类的构造方法被调用");
}
public static void main(String[] args){
System.out.println("main函数被调用");
new Test_Five();
}
}
class Six{
static{
System.out.println("父类的静态代码块被调用");
}
{
System.out.println("父类的非静态代码块被调用");
}
public Six(){
System.out.println("父类的构造方法被调用");
}
}
结果为:
我们对上述结果进行分析:
首先被调用的父类中的静态代码块,其后的是子类中的静态代码块,然后是main函数中的语句(如果main函数的语句在创建对象语句之前),再之后是父类的非静态代码块和父类的构造方法,最后是子类的非静态代码块和子类的构造方法.
参考博文:
1.https://blog.csdn.net/sinat_33921105/article/details/79509638
2.https://blog.csdn.net/weixin_36910300/article/details/78643455