问题代码:
public class Test1{
-
public static int k=0;
-
public static Test1 t1=new Test1("t1");
-
public static Test1 t2=new Test1("t2");
-
public static int i=print("i");
-
public static int n=99;
-
-
public int j=print("j");
-
- {
-
print("构造块");
- }
-
-
static{
-
print("静态块");
- }
-
-
public Test1(String str){
-
System.out.println((++k)+":"+str+"i="+i+"n="+n);
- ++i;++n;
- }
-
-
public static int print(Stringstr){
-
System.out.println((++k)+":"+str+"i="+i+"n="+n);
- ++n;
-
return ++i;
- }
-
-
public static void main(String...strings){
-
- }
- }
-
- 输出结果:
-
1:ji=0n=0
-
2:构造块i=1n=1
-
3:t1i=2n=2
-
4:ji=3n=3
-
5:构造块i=4n=4
-
6:t2i=5n=5
-
7:ii=6n=6
-
8:静态块i=7n=99
问题:i和n到底是什么时候声明的,public static Test1 t1=new Test1("t1");这句会去执行构造块和构造方法,但是这时候public static int i=print("i");并没执行,i是哪里出来的?它是按顺序先声明所有变量然后才从头再挨个赋值吗?
原因是:类的生命周期分为如下几个阶段,Loading,Linking,Initialization.
Loading之后会对class文件进行Verification(验证).然后是Preparation阶段,注意在这个阶段所有的类变量(class变量),会被默认初始化,int,long,short,浮点等基本类型初始化为0,引用初始化为null,boolean被初始化为 false.也就是到这个阶段各个static变量已经有默认的值了;后面会进入Resolution阶段,然后才是初始化( Initialization),这个阶段会执行static初始化,把变量初始化为你指定的值.也就是在这个阶段k=0;Test1 t1=new Test1("t1");才开始执行的,这时候i=print("i");还没有执行到,i仍然取在 Preparation阶段得到的默认值0.
参考: 深入java虚拟机
http://www.artima.com/insidejvm/ed2/lifetype.html
明白了这个问题,静态初始化语句使用较多的时候一定要注意保证正确性,合理组织static语句的顺序.
分享到:
相关推荐
例如,如果一个类需要在程序运行前设置一个常量数组,静态初始化块就是合适的选择。 ```java public class InitFiledBlockStatic { static int[] staticArray; static { // 静态初始化块中的代码 staticArray ...
44.java数组静态初始化.zip44.java数组静态初始化.zip44.java数组静态初始化.zip44.java数组静态初始化.zip44.java数组静态初始化.zip44.java数组静态初始化.zip44.java数组静态初始化.zip44.java数组静态初始化.zip...
52.java二维数组静态初始化.zip52.java二维数组静态初始化.zip52.java二维数组静态初始化.zip52.java二维数组静态初始化.zip52.java二维数组静态初始化.zip52.java二维数组静态初始化.zip52.java二维数组静态初始化....
它们与普通变量的区别在于,静态变量在程序执行期间只初始化一次,并且其值在函数调用之间得以保留。下面将详细解释易语言中静态变量的初始化、作用以及相关示例。 首先,我们要理解静态变量的生命周期。在易语言中...
详细介绍了Java的静态成员变量、静态数据块、非静态成员变量和非静态成员变量等初始化顺序
静态初始化: 手动输入数组元素,系统会根据元素个数,计算数组的长度. 数组动态初始化: 数据类型[] 数组名=new 数据类型[数据长度] eg: int[] arry=new int [3]; 数组静态初始化: 数据类型[] 数组名=new 数据类型[]{...
在 Java 中,静态变量的初始化过程可以被分为三个阶段:静态初始化、非静态初始化和执行构造函数。静态初始化是指在类加载时对静态变量的初始化。非静态初始化是指在实例创建时对实例变量的初始化。执行构造函数是指...
Java云笔记的初始化阶段是构建一个可运行的Web应用程序的关键步骤,这里的“初始化”通常指的是创建一个基础框架,包括前端界面和后端逻辑的初步设定。在这个场景中,我们关注的是前端部分,即HTML静态页面的构建。 ...
这意味着如果一个全局变量依赖于其他全局变量的初始化结果,必须确保这些依赖的变量已完成静态初始化。 初始化顺序方面,同一编译单元内的全局变量按照声明顺序进行初始化,但不同编译单元间的全局变量的初始化顺序...
4. **多线程环境**:如果多个线程同时加载同一个类,静态初始化块会被同步执行,确保线程安全。这意味着多个线程不会同时执行同一类的静态初始化块。 5. **继承关系**:子类会继承父类的静态初始化块,但不会重复...
Java中的对象初始化流程是编程实践中一个非常重要的概念,它涉及到类加载、静态初始化块、实例初始化块、构造器等多个方面。下面将详细解释这个过程。 首先,对象初始化流程的起点是程序的入口点,即`main`方法。当...
System.out.println("父类--静态初始化块"); } // 初始化块 { System.out.println(p_Field); System.out.println("父类--初始化块"); } // 构造器 public Parent() { System.out.println(...
以下是一个使用动态初始化和静态初始化的示例代码: TestD.java(动态初始化) ```java public class TestD { public static void main(String[] args[]) { int a[]; a = new int[3]; a[0] = 0; a[1] = 1; a...
在编程中,变量是存储数据的容器,而静态变量有别于普通变量,它的特点是生命周期较长且在程序执行期间只被初始化一次。在易语言中,静态变量的使用有以下几个关键点: 1. **声明与初始化**:在易语言中,静态变量...
例如,可能会有一个类包含静态和非静态初始化块,一个构造函数,以及一些静态和实例变量。通过观察它们的执行顺序,你将更好地理解Java的初始化流程。 总之,Java代码的初始化顺序是类加载的必然过程,涉及到静态和...
此外,静态初始化块只在类加载时执行一次,而初始化块(也称为实例初始化块)会在每次创建类的新实例时执行。这意味着静态成员和静态初始化块对于所有类的实例都是共享的,而实例成员和实例初始化块则是每个对象独有...
3. **父类静态成员变量及初始化块**:如果当前类继承自另一个类,则父类的静态成员变量和静态初始化块会在子类之前被初始化。 4. **实例成员变量的默认初始化**:创建对象时,默认情况下,实例成员变量会被初始化为...
3. **父类静态初始化块**:然后是第一个静态初始化块,输出 `"我输出的是父类静态块内容→" + BaseClass.basename`。由于 `basename` 已被初始化,因此输出结果为 `"我输出的是父类静态块内容→父类静态变量"`。 4...
### Java 类中静态域、块,非静态域、块,构造函数的初始化顺序 #### 一、概述 在 Java 编程语言中,类的初始化顺序对于理解程序的行为至关重要。特别是当涉及到静态域(静态变量)、非静态域(实例变量)、静态块...