`
得小白者天下得
  • 浏览: 7867 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

java静态成员变量的初始化

阅读更多
看过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静态和非静态成员变量初始化过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    php 静态变量的初始化

    } } 但是php中并没有一个类似java中的静态构造器/静态块的东西,就没有合适的时机对其进行初始化了。 对于共有的成员还有办法解决,例如: class A { static public $child; } A::$child = new B()

    java学习之神奇初始化

    如果有static,即静态成员定义,首先初始化static的变量,如,在类Cups中c3在c2前面,可是在输出的结果中,你可以发现,c2是在c3前执行的,这就是因为,所有的static都在第一时间被初始化。

    Java类中各成员初始化的顺序

    了解java中类各个成员的初始化顺序是非常重要的,这样你可以对类有全局的认识。不说太多,直接看下面的例子 class Father { static{ System.... return "父类静态成员变量的初始化" ; } public Fath

    Java开发者文档,分享日常学习的一些小知识点 .rar

     (1) 主类的超类由高到低按顺序初始化静态成员,无论静态成员是否为private。  (2) 主类静态成员的初始化。  (3) 主类的超类由高到低进行默认构造方法的调用。注意,在调用每一个超类的默认构造  方法前,先...

    Java并发--final关键字.docx

    在Java中变量可以分为成员变量和局部变量 成员变量 通常每个类中成员变量可以分为 类变量(static修饰的变量) 以及 实例变量 针对这两种类型的变量赋初始值的时机是不同的。 类变量可以再声明变量的时候直接赋...

    java基础非常典型的面试题目.wps

    1.成员变量的初始化 实例变量可以在定义处或者在构造方法中被显式初始化。如果在这两处都没有初始化,那么保留自动初始化时的默认值。final型的变量必须被显式初始化。 静态变量可以在定义处或者在静态代码块中被...

    java对象初始化顺序验证示例

    以下这段小程序对调用对象构造函数时,父类构造函数、成员变量初始化函数,以及非静态初始化块调用顺序进行验证,不考虑静态成员及静态初始化块

    Test.java关于静态的分析

    //静态成员变量 int j=0; //成员变量 public static void print(){ } //静态的块 static{ System.out.println("我是静态块,我自己调用自己"); //j++; i++; ...

    JAVA基础知识精华总结 收藏

    (1) 主类的超类由高到低按顺序初始化静态成员,无论静态成员是否为private。 (2) 主类静态成员的初始化。 (3) 主类的超类由高到低进行默认构造方法的调用。注意,在调用每一个超类的默认构造 方法前,先进行对此...

    Java开发技术大全(500个源代码).

    errorInit.java 演示变量初始化错误的程序 integerExample.java 演示各种整型变量的使用 isPrime.java 判断素数 leapYearByIf.java 用if语句判断闰年 leapYearByLogical.java 用逻辑表达式判断闰年 lowToUpper...

    JAVA编写飞机大战-千锋实训项目

    飞机大战的需求: ​ 1.游戏可以产生: 小敌机/大敌机/小蜜蜂 -> 随机(概率)产生 ​ 2.跟鼠标相关的操作: ​ a....加载(读取)图片 -> static{} -> 静态代码块,需要静态成员变量 b.获取父类中的成员变量

    JAVA笔记.zip

    不能访问实例成员 "> 静态变量 实例化前初始化 类装载时分配空间 多个对象共享同一内存空间 不能被垃圾收集线程收集 静态代码块 装载时运行 在main 之前 只运行一次 下次类再装载或创建对象时不运行 静态...

    Java 基础核心总结 +经典算法大全.rar

    类的初始化 成员初始化 构造器初始化初始化顺序 数组初始化 对象的销毁 对象作用域 this 和 super 访问控制权限继承 多态组合代理 向上转型static final 接口和抽象类接口 抽象类异常 认 识 Exception 什么是 ...

    实验03 Java面向对象编程1.doc

    ○2在Student类建立构造方法初始化各域的值,并统计学生人数count; ○3创建分别获得各域(学号,姓名,性别和年龄)的public方法,以及分别设置各域(学号,姓名,性别和年龄)值的public方法(即get、set方法);...

    Java提高篇之关键字static

     在Java中并不存在全局变量的概念,但是我们可以通过static来实现一个“伪全局”的概念,在Java中static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,当然也可以修饰代码块。  Java把内存分为...

    Java 语言基础 —— 非常符合中国人习惯的Java基础教程手册

    对象的使用包括引用对象的成员变量和方法,通过运算符·可以实现对变量的访问和方法的调 用,变量和方法可以通过设定一定的访问权限(见下面的例子)来允许或禁止其它对象对它的 访问。 我们先定义一个类 Point。 例子...

    疯狂JAVA讲义

    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和...

    Java经典面试题.pdf

    静态关键字用于修饰类的成员(方法、变量、代码块),使其在类加载时被初始化,并且可以通过类名直接访问。静态成员属于类本身,而不是类的实例。静态方法无法访问非静态成员。 4.什么是Java的final关键字? final...

Global site tag (gtag.js) - Google Analytics