`
ZangXT
  • 浏览: 118316 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

一个静态初始化的问题

阅读更多

问题代码: 

public class Test1{

  1. public static int k=0;
  2. public static Test1 t1=new Test1("t1");
  3. public static Test1 t2=new Test1("t2");
  4. public static int i=print("i");
  5. public static int n=99;
  6. public int j=print("j");
  7. {
  8. print("构造块");
  9. }
  10. static{
  11. print("静态块");
  12. }
  13. public Test1(String str){
  14. System.out.println((++k)+":"+str+"i="+i+"n="+n);
  15. ++i;++n;
  16. }
  17. public static int print(Stringstr){
  18. System.out.println((++k)+":"+str+"i="+i+"n="+n);
  19. ++n;
  20. return ++i;
  21. }
  22. public static void main(String...strings){
  23. }
  24. }
  25. 输出结果:
  26. 1:ji=0n=0
  27. 2:构造块i=1n=1
  28. 3:t1i=2n=2
  29. 4:ji=3n=3
  30. 5:构造块i=4n=4
  31. 6:t2i=5n=5
  32. 7:ii=6n=6
  33. 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静态初始化块和对象初始化块

    例如,如果一个类需要在程序运行前设置一个常量数组,静态初始化块就是合适的选择。 ```java public class InitFiledBlockStatic { static int[] staticArray; static { // 静态初始化块中的代码 staticArray ...

    44.java数组静态初始化.zip

    44.java数组静态初始化.zip44.java数组静态初始化.zip44.java数组静态初始化.zip44.java数组静态初始化.zip44.java数组静态初始化.zip44.java数组静态初始化.zip44.java数组静态初始化.zip44.java数组静态初始化.zip...

    52.java二维数组静态初始化.zip

    52.java二维数组静态初始化.zip52.java二维数组静态初始化.zip52.java二维数组静态初始化.zip52.java二维数组静态初始化.zip52.java二维数组静态初始化.zip52.java二维数组静态初始化.zip52.java二维数组静态初始化....

    易语言静态变量初始化

    它们与普通变量的区别在于,静态变量在程序执行期间只初始化一次,并且其值在函数调用之间得以保留。下面将详细解释易语言中静态变量的初始化、作用以及相关示例。 首先,我们要理解静态变量的生命周期。在易语言中...

    关于Java静态成员变量和静态初始化块等的初始化顺序的详细介绍

    详细介绍了Java的静态成员变量、静态数据块、非静态成员变量和非静态成员变量等初始化顺序

    数组动态初始化与静态初始化的区别

    静态初始化: 手动输入数组元素,系统会根据元素个数,计算数组的长度. 数组动态初始化: 数据类型[] 数组名=new 数据类型[数据长度] eg: int[] arry=new int [3]; 数组静态初始化: 数据类型[] 数组名=new 数据类型[]{...

    学习java静态数据初始化.doc

    在 Java 中,静态变量的初始化过程可以被分为三个阶段:静态初始化、非静态初始化和执行构造函数。静态初始化是指在类加载时对静态变量的初始化。非静态初始化是指在实例创建时对实例变量的初始化。执行构造函数是指...

    达内 java云笔记 初始化 静态页面

    Java云笔记的初始化阶段是构建一个可运行的Web应用程序的关键步骤,这里的“初始化”通常指的是创建一个基础框架,包括前端界面和后端逻辑的初步设定。在这个场景中,我们关注的是前端部分,即HTML静态页面的构建。 ...

    C++全局变量初始化的一点总结

    这意味着如果一个全局变量依赖于其他全局变量的初始化结果,必须确保这些依赖的变量已完成静态初始化。 初始化顺序方面,同一编译单元内的全局变量按照声明顺序进行初始化,但不同编译单元间的全局变量的初始化顺序...

    Java static静态初始快

    4. **多线程环境**:如果多个线程同时加载同一个类,静态初始化块会被同步执行,确保线程安全。这意味着多个线程不会同时执行同一类的静态初始化块。 5. **继承关系**:子类会继承父类的静态初始化块,但不会重复...

    对象初始化流程梳理对象初始化流程梳理

    Java中的对象初始化流程是编程实践中一个非常重要的概念,它涉及到类加载、静态初始化块、实例初始化块、构造器等多个方面。下面将详细解释这个过程。 首先,对象初始化流程的起点是程序的入口点,即`main`方法。当...

    java 静态非静态 字段方法 子类父类构造_初始化顺序!

    System.out.println("父类--静态初始化块"); } // 初始化块 { System.out.println(p_Field); System.out.println("父类--初始化块"); } // 构造器 public Parent() { System.out.println(...

    java数组初始化详解

    以下是一个使用动态初始化和静态初始化的示例代码: 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...

    易语言静态变量初始化源码.zip

    在编程中,变量是存储数据的容器,而静态变量有别于普通变量,它的特点是生命周期较长且在程序执行期间只被初始化一次。在易语言中,静态变量的使用有以下几个关键点: 1. **声明与初始化**:在易语言中,静态变量...

    java代码的初始化顺序demo

    例如,可能会有一个类包含静态和非静态初始化块,一个构造函数,以及一些静态和实例变量。通过观察它们的执行顺序,你将更好地理解Java的初始化流程。 总之,Java代码的初始化顺序是类加载的必然过程,涉及到静态和...

    java面试题-类的初始化顺序.doc

    此外,静态初始化块只在类加载时执行一次,而初始化块(也称为实例初始化块)会在每次创建类的新实例时执行。这意味着静态成员和静态初始化块对于所有类的实例都是共享的,而实例成员和实例初始化块则是每个对象独有...

    java中类的初始化顺序

    3. **父类静态成员变量及初始化块**:如果当前类继承自另一个类,则父类的静态成员变量和静态初始化块会在子类之前被初始化。 4. **实例成员变量的默认初始化**:创建对象时,默认情况下,实例成员变量会被初始化为...

    类初始化顺序示例讲解

    3. **父类静态初始化块**:然后是第一个静态初始化块,输出 `"我输出的是父类静态块内容→" + BaseClass.basename`。由于 `basename` 已被初始化,因此输出结果为 `"我输出的是父类静态块内容→父类静态变量"`。 4...

    java类中静态域、块,非静态域、块,构造函数的初始化顺序

    ### Java 类中静态域、块,非静态域、块,构造函数的初始化顺序 #### 一、概述 在 Java 编程语言中,类的初始化顺序对于理解程序的行为至关重要。特别是当涉及到静态域(静态变量)、非静态域(实例变量)、静态块...

Global site tag (gtag.js) - Google Analytics