文档章节

存在继承时,Static与Constructor加载顺序

镜子哥哥
 镜子哥哥
发布于 2016/11/19 15:53
字数 1042
阅读 5
收藏 0

#类的加载过程 类的生命周期

  1. 装载:查找和导入Class文件;

  2. 链接:把类的二进制数据合并到JRE中;

    • 校验:检查载入Class文件数据的正确性;

    • 准备:给类的静态变量分配存储空间;

    • 解析:将符号引用转成直接引用;

  3. 初始化:对类的静态变量,静态代码块执行初始化操作

#类初始化

  1. 遇到new、getstatic、putstatic或invokestatic这4条字节码指令时,如果类没有进行过初始化,则需要先触发其初始化。生成这4条指令的最常见的Java代码场景是:使用new关键字实例化对象的时候,读取或设置一个类的静态字段(被final修饰、已在编译期把结果放入常量池的静态字段除外)的时候,以及调用一个类的静态方法的时候。

  2. 使用java.lang.reflect包的方法对类进行反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化。

  3. 当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化。

  4. 当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的那个类),虚拟机会先初始化这个主类。

#实例化与初始化

  • 实例化是初始化的其中一部分,初始化还包括类本身的加载,比如静态代码的执行和静态成员变量的初始化。
  • 实例化就是new一个新的对象到堆内存空间,但静态化的代码就是类本身拥有的内存空间,被所有new的实例对象共享。
  • 不管new多少对象,类的静态代码部分只执行一次,就是在初始化时。

#一个demo ###代码

class StaticInitParent {
    static int i = 1;
    static int j;
    static {
    	int i = 10;
    	System.out.println("父类静态代码块1, i = " + i + ", j = " + j);
    } 
    public StaticInitParent() {
    	System.out.println("父类构造函数");
    	{
    		System.out.println("父类构造代码块");
    	}
    }
    {
    	System.out.println("父类普通代码块");
    }
    static void print(){
    	System.out.println("父类静态方法  i = " + i + ", j = " + ++j);
    }
    static {
    	System.out.println("父类静态代码块2, j = " + j);
    }
}

public class StaticInit extends StaticInitParent{
	static {
	    i++;
	    System.out.println("子类静态代码块1, i = " + i + ", j = " + j);
	} 
	
	public StaticInit() {
	    System.out.println("子类构造函数");
	    {
	    	System.out.println("子类构造代码块");
	    }
	}
	
	{
	    System.out.println("子类普通代码块");
	}
	
	static void print(){
	    System.out.println("子类静态方法  i = " + i + ", j = " + ++j);
	}
	
	static {
	    System.out.println("子类静态代码块2, j = " + j);
	}
	
	public static void main(String[] args){
		System.out.println("=====");
		StaticInit.print();
		StaticInit sta = new StaticInit();
	}
}

###运行结果

父类静态代码块1, i = 10, j = 0
父类静态代码块2, j = 0
子类静态代码块1, i = 2, j = 0
子类静态代码块2, j = 0
 =====
子类静态方法  i = 2, j = 1
父类普通代码块
父类构造函数
父类构造代码块
子类普通代码块
子类构造函数
子类构造代码块

###分析

  1. 首先加载父类的static变量和方法,顺序 和代码顺序有关;
  • 静态代码块中的变量是内部有效的,这样能理解变量 i 的输出;
  1. 然后加载子类的static变量和方法,顺序同样与代码顺序有关;
  • 子类继承了父类静态变量i的值1,在执行i++后输出2;
  1. 执行main()方法;
  2. 根据代码顺序,执行子类的静态函数;
  3. 接下来开始实例化,加载父类的普通代码块;
  • 这里也可以看出并没有再次执行静态代码部分;
  1. 加载父类的构造函数(内部执行顺序与代码顺序有关);
  2. 加载子类的普通代码块;
  3. 加载子类的构造函数,实例化结束;

#结论 当该类有父类的时候,类的加载过程是:(以下内容均处于初始化阶段)

父类的static成员变量和方法-->该类的static变量和方法-->main()方法-->父类的普通成员变量和方法-->父类的构造方法->该类的普通成员变量和方法-->该类的构造方法-->结束

© 著作权归作者所有

共有 人打赏支持
镜子哥哥
粉丝 1
博文 19
码字总数 14425
作品 0
广州
私信 提问
constructor / destructor

attribute表示属性,是Clang提供的一种源码注释,方便开发者向编译器表达诉求,一般以attribute(*)的方式出现在代码中。为了方便使用,一些常用属性被定义成了宏,经常出现在系统头文件中。比...

HeroHY
11/17
0
0
编写高质量代码:改善Java程序的151个建议 --[98~105]

建议的采用顺序是List中泛型顺序依次为T、?、Object (1)、List是确定的某一个类型   List表示的是List集合中的元素都为T类型,具体类型在运行期决定;List<?>表示的是任意类型,与List类似...

西北野狼
08/13
0
0
Java 语言中的实例初始化块 ( IIB) 详解

在 Java 语言中的类初始化块 文章中我们简单的介绍了下 Java 中的实例初始化块 ( IIB )。不过我觉得介绍的有点简单了,于是,再写一篇文章详细介绍下吧。 Java 语言中,存在三种操作:方法 ...

beves
10/14
0
0
干货——详解Java中的关键字

在平时编码中,我们可能只注意了这些static,final,volatile等关键字的使用,忽略了他们的细节,更深层次的意义。 本文总结了Java中所有常见的关键字以及一些例子。 static 关键字 概述: ...

Janti
07/22
0
0
java变量,初始化快,构造函数的执行顺序

对于JAVA中类的初始化是一个很基础的问题,其中的一些问题也是易被学习者所忽略。当在编写代码的时候碰到时,常被这些问题引发的错误,感觉莫名其妙。而且现在许多大公司的面试题,对于这方面...

清风傲剑
2014/08/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

case when then

case具有两种格式。简单case函数和case搜索函数。 --简单case函数case sex when '1' then '男' when '2' then '女’ else '其他' end--case搜索函数case when sex = '1' the...

architect刘源源
12分钟前
0
0
Kubernetes探秘—kubelet的配置参数

kubelet是Kubernetes中的核心组件,需要在每一个节点安装,也是kubernetes集群启动的第一个服务。kubelet的参数存放在多个目录,修改时如果不完整就会导致各种错误,下面我们kubelet的参数存...

openthings
15分钟前
0
0
如何通过 MySQL 的二进制日志恢复数据库数据

经常有网站管理员因为各种原因和操作,导致网站数据误删,而且又没有做网站备份,结果不知所措,甚至给网站运营和盈利带来负面影响。所以本文我们将和大家一起分享学习下如何通过 MySQL 的二...

吴伟祥
24分钟前
1
0
org.apache.catalina.startup.Catalina stopServer SEVERE: Could not contact localhost:8005. Tomcat may

org.apache.catalina.startup.Catalina stopServer SEVERE: Could not contact localhost:8005. Tomcat may 2017年07月21日 14:52:10 子木HAPPY阳VIP 阅读数:14134 标签: tomcatnginx 更多......

linjin200
26分钟前
1
0
线下工坊|Blockchain Coding Day:零基础教你开发DAPP(北京)

我们的目标是通过编程学习让你更了解区块链技术。这将对区块链开发初学者一次很好的体验。这里需要强调一下,编程零基础也能学会。 我们将以小组的形式,由教练带领学员完成DAPP开发。每位学...

HiBlock
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部