看过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静态和非静态成员变量初始化过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
} } 但是php中并没有一个类似java中的静态构造器/静态块的东西,就没有合适的时机对其进行初始化了。 对于共有的成员还有办法解决,例如: class A { static public $child; } A::$child = new B()
如果有static,即静态成员定义,首先初始化static的变量,如,在类Cups中c3在c2前面,可是在输出的结果中,你可以发现,c2是在c3前执行的,这就是因为,所有的static都在第一时间被初始化。
了解java中类各个成员的初始化顺序是非常重要的,这样你可以对类有全局的认识。不说太多,直接看下面的例子 class Father { static{ System.... return "父类静态成员变量的初始化" ; } public Fath
(1) 主类的超类由高到低按顺序初始化静态成员,无论静态成员是否为private。 (2) 主类静态成员的初始化。 (3) 主类的超类由高到低进行默认构造方法的调用。注意,在调用每一个超类的默认构造 方法前,先...
在Java中变量可以分为成员变量和局部变量 成员变量 通常每个类中成员变量可以分为 类变量(static修饰的变量) 以及 实例变量 针对这两种类型的变量赋初始值的时机是不同的。 类变量可以再声明变量的时候直接赋...
1.成员变量的初始化 实例变量可以在定义处或者在构造方法中被显式初始化。如果在这两处都没有初始化,那么保留自动初始化时的默认值。final型的变量必须被显式初始化。 静态变量可以在定义处或者在静态代码块中被...
以下这段小程序对调用对象构造函数时,父类构造函数、成员变量初始化函数,以及非静态初始化块调用顺序进行验证,不考虑静态成员及静态初始化块
//静态成员变量 int j=0; //成员变量 public static void print(){ } //静态的块 static{ System.out.println("我是静态块,我自己调用自己"); //j++; i++; ...
(1) 主类的超类由高到低按顺序初始化静态成员,无论静态成员是否为private。 (2) 主类静态成员的初始化。 (3) 主类的超类由高到低进行默认构造方法的调用。注意,在调用每一个超类的默认构造 方法前,先进行对此...
errorInit.java 演示变量初始化错误的程序 integerExample.java 演示各种整型变量的使用 isPrime.java 判断素数 leapYearByIf.java 用if语句判断闰年 leapYearByLogical.java 用逻辑表达式判断闰年 lowToUpper...
飞机大战的需求: 1.游戏可以产生: 小敌机/大敌机/小蜜蜂 -> 随机(概率)产生 2.跟鼠标相关的操作: a....加载(读取)图片 -> static{} -> 静态代码块,需要静态成员变量 b.获取父类中的成员变量
不能访问实例成员 "> 静态变量 实例化前初始化 类装载时分配空间 多个对象共享同一内存空间 不能被垃圾收集线程收集 静态代码块 装载时运行 在main 之前 只运行一次 下次类再装载或创建对象时不运行 静态...
类的初始化 成员初始化 构造器初始化初始化顺序 数组初始化 对象的销毁 对象作用域 this 和 super 访问控制权限继承 多态组合代理 向上转型static final 接口和抽象类接口 抽象类异常 认 识 Exception 什么是 ...
○2在Student类建立构造方法初始化各域的值,并统计学生人数count; ○3创建分别获得各域(学号,姓名,性别和年龄)的public方法,以及分别设置各域(学号,姓名,性别和年龄)值的public方法(即get、set方法);...
在Java中并不存在全局变量的概念,但是我们可以通过static来实现一个“伪全局”的概念,在Java中static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,当然也可以修饰代码块。 Java把内存分为...
对象的使用包括引用对象的成员变量和方法,通过运算符·可以实现对变量的访问和方法的调 用,变量和方法可以通过设定一定的访问权限(见下面的例子)来允许或禁止其它对象对它的 访问。 我们先定义一个类 Point。 例子...
5.3.2 成员变量的初始化和内存中的运行机制 128 5.3.3 局部变量的初始化和内存中的运行机制 130 5.3.4 变量的使用规则 130 5.4 隐藏和封装 132 5.4.1 理解封装 132 5.4.2 使用访问控制符 132 5.4.3 package和...
静态关键字用于修饰类的成员(方法、变量、代码块),使其在类加载时被初始化,并且可以通过类名直接访问。静态成员属于类本身,而不是类的实例。静态方法无法访问非静态成员。 4.什么是Java的final关键字? final...