看过Thinking in java的人都知道,在不考虑父类的情况下,类的初始化顺序相对简单,总体是先静态的,然后是非静态的。这里都包括成员变量和代码块。对于静态变量和静态代码块,不管它们在何处定义,总是按照其先后顺序进行初始化。同理,非静态变量和非静态代码块也是如此。
下面上热菜:
public class Test1 {
public static int k = 0;
public static Test1 initOrder1 = new Test1("t1");
public static Test1 initOrder2 = new Test1("t2");
public static final int m = -1;
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 + " m=" + m);
++i;
++n;
}
public static int print(String str) {
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n + " m=" + m);
++n;
return ++i;
}
public static void main(String[] args) {
Test1 initOrder = new Test1("init");
}
}
什么!!!居然还有这样的的:
public static Test1 initOrder1 = new Test1("t1");
对我这种小白来说,这太不能理解了。伤脑细胞!
我们先看看答案吧:
1:j i=0 n=0 m=-1
2:构造块 i=1 n=1 m=-1
3:t1 i=2 n=2 m=-1
4:j i=3 n=3 m=-1
5:构造块 i=4 n=4 m=-1
6:t2 i=5 n=5 m=-1
7:i i=6 n=6 m=-1
8:静态块 i=7 n=99 m=-1
9:j i=8 n=100 m=-1
10:构造块 i=9 n=101 m=-1
11:init i=10 n=102 m=-1
按照惯例,程序进入main()方法后,在调用new Test1()的一瞬间,Test1开始初始化了,k=0。当进行到public static Test1 initOrder1 = new Test1("t1");的时候,就要开始实例化了,所以接下来的静态变量都先等着,等排在前面的initOrder1先办完事了,才有你们这群小屁孩的事。因为静态变量属于类,而非类的实例,所以我initOrder1只好先对实例变量和非静态代码块下手了(小鲜肉,我来了。。。)。所以就会执行如下语句:
public int j = print("j");
{
print("构造块");
}
得到输出:
1:j i=0 n=0 m=-1
2:构造块 i=1 n=1 m=-11
然后再调用构造器,就可以完成对initOrder1的初始化,顺便打印出了
3:t1 i=2 n=2 m=-1
接下来该初始化initOrder2了,原理同上。打印出:
4:j i=3 n=3 m=-1
5:构造块 i=4 n=4 m=-1
6:t2 i=5 n=5 m=-1
然后继续其他成员的初始化。注意,当初始化到了
public static int n = 99;
就会初始化静态代码块哟,要注意哈。别以为是顺序下来的。当初始化全部完成后,然后调用Test1("init"),至此,完成了mian()方法中的变量初始化。大功告成。
在虚拟机进行类加载的过程中,有一个准备阶段。准备阶段是正式为类变量分配内存并设置初始值的阶段,而且变量所使用的内存都将在方法区中进行分配。强调一下,此时金分配内存的是类变量(即被static修饰的变量),不包括实例变量,实例变量会和对象实例化的时候随着对象一起分配到java堆中。而且,在准备阶段过后,类变量如k和n的值为0, 而非通过=符号来赋值0和99。但是对于final static的变量m来说,情况就有点不一样。m在准备阶段就会被赋予初值-1,并放入常量池中。
如果有什么说错或者不清楚的地方,欢迎各位看官不吝批评指正。
分享到:
相关推荐
详细介绍了Java的静态成员变量、静态数据块、非静态成员变量和非静态成员变量等初始化顺序
Java静态和非静态成员变量初始化过程解析 Java静态和非静态成员变量初始化过程解析是Java语言中一个非常重要的概念。了解Java静态和非静态成员变量的初始化过程对大家的学习或者工作具有一定的参考学习价值。 首先...
Java 变量初始化详解 Java 变量初始化是 Java 语言的基础知识点之一,但也往往被学习者所忽略。 Java 变量初始化的时机是指在 Java 语言中变量的初始化过程,包括变量的声明、初始化和赋值的步骤。 Java 变量声明 ...
// 静态成员变量初始化 public static TestA a = new TestA(); // 静态初始化块 static { System.out.println("静态初始化"); } // 实例成员变量初始化 public static TestB b = new TestB(); public ...
静态初始化块常用于设置类级别的变量,或者执行只应执行一次的初始化操作。例如,如果一个类需要在程序运行前设置一个常量数组,静态初始化块就是合适的选择。 ```java public class InitFiledBlockStatic { ...
2. **父类静态成员变量初始化**:接下来,执行 `basename = "父类静态变量"` 这一行,将 `basename` 的值设置为 `"父类静态变量"`。 3. **父类静态初始化块**:然后是第一个静态初始化块,输出 `"我输出的是父类...
总的来说,使用静态成员变量来计算Java程序中实例化的对象数量是一种实用的技术,可以帮助开发者更好地理解他们的代码是如何消耗内存的。然而,对于更复杂的内存分析,可能需要依赖于Java虚拟机(JVM)提供的工具,...
在 Java 中,数组的初始化可以分为静态初始化和动态初始化。 静态初始化是指在定义数组时同时初始化数组的值,例如:`int[] a = {1, 2, 3};`。 动态初始化是指在定义数组时不初始化数组的值,而是在后续的代码中...
在编程语言中,如C++或Java,类的成员变量分为两种主要类型:静态成员变量(Static Member Variables)和非静态成员变量(也称为实例变量)。这两种变量在使用和存储方式上存在显著差异,这对于理解和编写高效、清晰...
在编程语言中,如C++或Java,`static`关键字有着重要的作用,它主要用于定义静态成员变量和静态成员函数。本文将深入解析`static`的关键特性,并探讨它们在面向过程和面向对象编程中的应用。 首先,静态成员变量,...
4. **子类成员变量初始化**:最后,执行子类的非静态成员变量初始化。 在实际编程中,`super`关键字用于引用父类的成员。例如,`super.someMethod()`调用父类的`someMethod()`方法,`super.someVariable`访问父类的...
然而,如果你想要将静态变量初始化为一个对象,PHP并不支持像Java那样的静态构造器或静态初始化块。在这种情况下,你需要在代码的某个时刻显式地调用一个方法来完成初始化。例如: ```php class A { static ...
总之,Java代码的初始化顺序是类加载的必然过程,涉及到静态和实例初始化块、构造函数、成员变量初始化以及继承关系的影响。这个demo是学习和理解这些概念的重要工具,通过实际操作可以加深对Java内存管理和对象生命...
3. **静态与非静态**: 静态成员变量属于类,而非实例。这意味着所有类的实例共享同一份静态变量。非静态成员变量则是每个实例独有的。 4. **this关键字**: 在方法中,使用`this`关键字可以引用当前对象的成员变量,...
### Java静态数据初始化详解 #### 一、Java静态初始化概述 在Java中,静态初始化主要用于在类被加载时初始化类的静态成员。这种初始化只会在类首次被加载时发生一次,之后创建该类的新实例时不会再次触发。静态...
这个顺序可能会导致一些有趣的现象,例如,在父类的构造器中使用某个还未初始化的子类静态成员变量(如果子类静态成员变量的初始化依赖于父类的某些数据或者执行顺序),就可能产生意料之外的行为,因为按照初始化...
静态成员包括静态变量、静态方法和静态初始化块。 1、静态变量 静态变量是指属于类的变量,它们的值是共享的,所有实例都可以访问到同一个静态变量。在上面的代码中,`static int z;`就是一个静态变量。静态变量是...
在加载过程中,JVM会对该类的静态成员变量进行初始化,只需一次。这样,就不会出现死循环的问题。 三、结论 在Java编程中,非静态成员变量可能会引发死循环的出现,而静态成员变量则不会。为了避免死循环的出现,...
在静态块中,我们通常进行一些需要进行异常捕获的静态变量的初始化。 例如: ```java public class StaticExample { static { System.out.println("StaticExample static block"); str = "Test"; setCount(2);...
2. **对象的生成及成员变量初始化**: 当创建一个新对象时,成员变量的初始化过程分为两个阶段: - 首先,执行实例初始化块(如果存在)。实例初始化块中的代码会在每次创建新对象时运行,且在构造函数调用之前。 ...