文档章节

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

镜子哥哥
 镜子哥哥
发布于 2016/11/19 15:53
字数 1042
阅读 5
收藏 0
点赞 0
评论 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
广州
java变量,初始化快,构造函数的执行顺序

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

清风傲剑 ⋅ 2014/08/19 ⋅ 0

Java 走向C++

本文不涉及一些微妙蛋疼的语法比较, 关注的是宏观方面, 当然后期逐步更新如果, 如果觉得必要, 可能会加上. 议题之一: 初始化的比较 1. CPP基类的任何类构造函数会默认调用父类的不带参数的构...

晨曦之光 ⋅ 2012/03/09 ⋅ 0

Java 走向C++

本文不涉及一些微妙蛋疼的语法比较, 关注的是宏观方面, 当然后期逐步更新如果, 如果觉得必要, 可能会加上. 议题之一: 初始化的比较 1. CPP基类的任何类构造函数会默认调用父类的不带参数的构...

晨曦之光 ⋅ 2012/03/09 ⋅ 0

JVM 的类初始化机制

当你在 Java 程序中对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机...

jiacai2050 ⋅ 2017/01/15 ⋅ 0

js es6 类的使用

声明和定义 es5 声明一个构造函数: es6 声明一个类: 以上两者相比之下,很可以看出,es6类函数比es5构造函数,代码量更少,并且结构层次更加简洁明了。 有些地方需要注意的是: es5存在变量...

阿豪boy ⋅ 02/16 ⋅ 0

ECMAScript 6教程 (三) Class和Module(类和模块)

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出 原文连接,博客地址为 http://www.cnblogs.com/jasonnode/ 。该系列课程是汇智网 整理编...

笔阁 ⋅ 2015/07/20 ⋅ 0

Java和Android ClassLoder对比以及Class加载过程

Java的ClassLoder的父子关系如下:Bootstrap--ExtClassClassLoader---AppClassLoader。 JVM启动时先运行启动类加载器Bottstrap,主要加载Java核心API;然后加载扩展类加载器ExtClassLoder,该...

JasmineBen ⋅ 05/23 ⋅ 0

java类的加载顺序

一个java类的加载顺序,今天做了一个实验,结果如下 超类的静态成员 超类的静态块 子类的静态成员 子类的静态块 超类的非静态成员 超类的构造函数 子类的非静态成员 子类的构造函数 class Pa...

偶尔诗文 ⋅ 2015/12/21 ⋅ 0

Java基础语言(4)

一,super(),super,this(),this 1,this:在运行期间,哪个对象调用this所在的方法,this就代表哪个对象。 2,this():调用本类的其他构造器,按照参数调用构造器,必须在构造器中使用。必...

Bug-Killer ⋅ 2016/04/09 ⋅ 0

Java静态代码块和非静态代码块、类加载、构造对象的机制

温故而知新,代码块这东西时间一长一些东西容易忘记,比如静态代码块、非静态代码款、静态成员变量初始化、动态成员变量初始化、构造方法调用、类加载等等的顺序机制是怎么样的? 话不多说了...

HappyBKs ⋅ 2015/08/17 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

NFS介绍 NFS服务端安装配置 NFS配置选项

NFS介绍 NFS是Network File System的缩写;这个文件系统是基于网路层面,通过网络层面实现数据同步 NFS最早由Sun公司开发,分2,3,4三个版本,2和3由Sun起草开发,4.0开始Netapp公司参与并主导...

lyy549745 ⋅ 34分钟前 ⋅ 0

Spring AOP 源码分析 - 筛选合适的通知器

1.简介 从本篇文章开始,我将会对 Spring AOP 部分的源码进行分析。本文是 Spring AOP 源码分析系列文章的第二篇,本文主要分析 Spring AOP 是如何为目标 bean 筛选出合适的通知器(Advisor...

java高级架构牛人 ⋅ 57分钟前 ⋅ 0

HTML-标签手册

标签 描述 <!--...--> 定义注释。 <!DOCTYPE> 定义文档类型。 <a> 定义锚。超链接 <abbr> 定义缩写。 <acronym> 定义只取首字母的缩写。 <address> 定义文档作者或拥有者的联系信息。 <apple......

ZHAO_JH ⋅ 58分钟前 ⋅ 0

SylixOS在t_main中使用硬浮点方法

问题描述 在某些使用场景中,应用程序不使用动态加载的方式执行,而是跟随BSP在 t_main 线程中启动,此时应用代码是跟随 BSP 进行编译的。由于 BSP 默认使用软浮点,所以会导致应用代码中的浮...

zhywxyy ⋅ 今天 ⋅ 0

JsBridge原理分析

看了这个Github代码 https://github.com/lzyzsd/JsBridge,想起N年前比较火的Hybrid方案,想看看现在跨平台调用实现有什么新的实现方式。代码看下来之后发现确实有点独特之处,这里先把核心的...

Kingguary ⋅ 今天 ⋅ 0

Intellij IDEA神器常用技巧五-真正常用快捷键(收藏级)

如果你觉得前面几篇博文太啰嗦,下面是博主多年使用Intellij IDEA真正常用快捷键,建议收藏!!! sout,System.out.println()快捷键 fori,for循环快捷键 psvm,main方法快捷键 Alt+Home,导...

Mkeeper ⋅ 今天 ⋅ 0

Java 静态代码分析工具简要分析与使用

本文首先介绍了静态代码分析的基本概念及主要技术,随后分别介绍了现有 4 种主流 Java 静态代码分析工具 (Checkstyle,FindBugs,PMD,Jtest),最后从功能、特性等方面对它们进行分析和比较,...

Oo若离oO ⋅ 今天 ⋅ 0

SpringBoot自动配置小记

spring-boot项目的特色就在于它的自动配置,自动配置就是开箱即用的本源。 不过支持一个子项目的自动配置,往往比较复杂,无论是sping自己的项目,还是第三方的,都是如此。刚接触会有点乱乱...

大_于 ⋅ 今天 ⋅ 0

React jsx 中写更优雅、直观的条件运算符

在这篇文字中我学到了很多知识,同时结合工作中的一些经验也在思考一些东西。比如条件运算符 Conditional Operator condition ? expr_if_true : expr_if_false 在jsx中书写条件语句我们经常都...

开源中国最帅没有之一 ⋅ 今天 ⋅ 0

vim编辑模式与命令模式

5.5 进入编辑模式 从编辑模式返回一般模式“Esc” 5.6 vim命令模式 命令 :“nohl”=no high light 无高亮,取消内容中高亮标记 "x":保存退出,和wq的区别是,当进入一个文件未进行编辑时,使...

弓正 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部