JAVA类加载与初始化顺序

 

类的生命周期

7个阶段依次为:Loading Verification Preparation Resolution Initialization Using Unloading

类加载的双亲委派模型

各个加载器都是先委托自己的父加载器加载类,若确实没加载到再自己来加载

于是java默认的类查找加载顺序是自顶向下的,树状结构

双亲委托的意图是保证java类型体系中最基础的行为一致,优先加载JDK中的类

加载器主要有四种:

  • jvm启动类加载器bootstrap loader,用c++实现为jvm的一部分(仅指sun的hotspot),负责 JAVA_HOME/lib下面的类库中的类的加载,这个加载器,java程序无法引用到。

  • 扩展类加载器Extension Loader,由sun.misc.Launcher$ExtClassLoader类实现,可在java中使用,负责JAVA_HOME/lib/ext 目录和java.ext.dir目录中类库的类的加载。

  • 应用系统类加载器Application System Loader,由sun.misc.Louncher$AppClassLoader实现,负责加载用户类路径中类库中的类,如果没有使用自定义的加载器,这个就是默认的 加载器!

  • 用户自定义加载器 自己定义从哪里加载类的二进制流

 

加载 验证 准备 初始化和卸载 的顺序是确定的,而“解析”不一定在初始化之前,很有可能在初始化之后,实现java的伟大特性。

package com.cyb.diffcult.类加载;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 作者 : iechenyb<br>
 * 类描述: final 修饰的为常量 子类继承父类时的初始化顺序 
 * 1.首先初始化父类的static变量和块,按出现顺序
 * 2.初始化子类的static变量和块,按出现顺序 
 * 3.初始化父类的普通变量,调用父类的构造函数 
 * 4.初始化子类的普通变量,调用子类的构造函数<br>
 * 创建时间: 2018年1月18日
 */
public class Singleton2 {
	Log log = LogFactory.getLog(getClass());
	public static final int a = init(5, "static final int a");
	public static int counter1;// 在构造方法*
	public static int counter2 = init2("static int c2", 120);// 在构造方法执行之后执行
	public final int c = init(6, "final int c");
	public int counter3 = init3("int c3", 110);// 初始化-最后
	public static final int b = init(4, "static final int b");
	public final int d = init(7, " final int d");
	public static int counter4 = init2("static int c4", 0);// 在构造方法执行之后执行

	static {
		System.out.println("静态语句块1");
	}

	private Singleton2(String msg) {
		System.out.println(msg);
	}

	private static int init(int num, String bs) {
		System.out.println("初始化常量" + bs);
		return num;
	}

	private Singleton2() {
		System.out.println("构造方法执行!");
		++counter1;
		++counter2;
		++counter3;
	}

	static {
		System.out.println("静态语句块2");
	}
	private static Singleton2 sin = new Singleton2();// 与静态语句块按照顺序执行

	public static int init2(String msg, int val) {
		System.out.println(msg);
		return val;
	}

	public int init3(String msg, int val) {
		System.out.println(msg);
		return val;
	}

	public static Singleton2 getInstance() {
		return sin;
	}

	public static void main(String[] args) {
		Singleton2 sin = Singleton2.getInstance();
		System.out.println(sin.counter1);// 1
		System.out.println(sin.counter2);// 1
		System.out.println(sin.counter3);// 110->666
		
	}
	/**
	 *  初始化常量static final int a
		static int c2
		初始化常量static final int b
		static int c4
		静态语句块1
		静态语句块2
		初始化常量final int c
		int c3
		初始化常量 final int d
		构造方法执行!
		1
		121
		111
	 */
}

执行顺序:

/**
 * 常量分 普通常量 和静态常量
 * 作者 : iechenyb<br>
 * 类描述: final 修饰的为常量 子类继承父类时的初始化顺序 
 * 1.首先初始化父类的static变量和块,按出现顺序
 * 2.初始化子类的static变量和块,按出现顺序 
 * 3.初始化父类的普通变量,调用父类的构造函数 
 * 4.初始化子类的普通变量,调用子类的构造函数<br>
 * 创建时间: 2018年1月18日
 */

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值