package com.lanou.Test;
public class Static_Main {
public static void main(String[] args) {
staticFunection();
}
static Static_Main st = new Static_Main();
{
System.out.println("2");
}
static {
System.out.println("1");
}
public Static_Main() {
System.out.println("3");
System.out.println("a =" + a + ", b=" + b);
}
public static void staticFunection() {
System.out.println("4");
System.out.println("静态方法内部: b=" + b);
}
int a = 110;
static int b = 112;
}
2
3
a =110, b=0
1
4
静态方法内部: b=112
在执行时也是按照顺序执行 , 如果将变量放在最前面 , 那么第一个初始化时就会初始化变量 , 那么b就会被赋值 .
1.类的生命周期是:加载->验证->准备->解析->初始化->使用->卸载,只有在准备阶段和初始化阶段才会涉及类变量的初始化和赋值,因此只针对这两个阶段进行分析;
2.类的准备阶段需要做是为类变量分配内存并设置默认值,因此类变量st为null、b为0;(需要注意的是如果类变量是final在加载阶段就已经完成了初始化,可以把b设置为final试试);3.类的初始化阶段需要做是执行类构造器(类构造器是编译器收集所有静态语句块和类变量的赋值语句按语句在源码中的顺序合并生成类构造器,对象的构造方法是init,类的构造方法是cinit,可以在堆栈信息中看到),因此先执行第一条静态变量的赋值语句即st = new StaticTest (),此时会进行对象的初始化,对象的初始化是先初始化成员变量再执行构造方法,因此打印2->设置a为110->执行构造方法(打印3,此时a已经赋值为110,但是b只是设置了默认值0,并未完成赋值动作),等对象的初始化完成后继续执行之前的类构造器的语句,接下来就不详细说了,按照语句在源码中的顺序执行即可;
但是还有一种情况是 : 如果开始不去在类中定义静态的对象,将对象的创建放在主函数中
static Static_Main st = new Static_Main();
那么代码的执行顺序就完全不一样;
package com.lanou.Test; public class Static_Main { public static void main(String[] args) { new Static_Main(); staticFunection(); } // static Static_Main st = new Static_Main(); { System.out.println("2"); } static { System.out.println("1"); } public Static_Main() { // TODO Auto-generated constructor stub System.out.println("3"); System.out.println("a =" + a + ", b=" + b); } public static void staticFunection() { System.out.println("4"); System.out.println("静态方法内部: b=" + b); } int a = 110; static int b = 112; }
1 2 3 a =110, b=112 4 静态方法内部: b=112在这个执行过程中 , 对象的实例化在主函数中执行, 那么代码的执行顺序就是按照顺序 : 静态代码块 --->主函数内部代码的顺序执行--->(如果 new 了对象)动态代码块 --->构造函数-->其他方法
---> 构造函数
这也是按照顺序执行的 , 因为主函数是入口 .
并且对变量的赋值, 在其执行完静态函数时已经赋值完毕