jvm 初始化

news/2024/7/7 15:11:10
package test;

public class A {
	private static A a = new A();

	private B b = B.getInstance();

	private A() {

	}

	public static A getInstance() {
		System.out.println("A被调用");
		return a;
	}

	public void test() {
		System.out.println(b);
	}
}

 

package test;

public class B {
	private static B b = new B();

	private A a = A.getInstance();

	private B() {

	}

	public static B getInstance() {
		System.out.println("B被调用");
		return b;
	}

	public void test() {
		System.out.println(a);
	}
}

 

package test;


/**
 * 面先说一下环境,比如现在有两个类,A和B,两个类都是单例类,这个时候如果A有个B的实例变量,B有个A的实例变量,
 * 会发生什么情况呢?开始我以为会出现栈溢出。但是让我迷惑的是,居然没问题。只是其中一个类的 实例变量会是NULL。
 * 下面看代码。 

 * @author zhang_zengmin
 *
 */
public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		B b = B.getInstance();
		b.test();
		System.out.println("==========");
		A a = A.getInstance();
		a.test();

		// A a = A.getInstance();
		// a.test();
		// System.out.println("==========");
		// B b = B.getInstance();
		// b.test();
		// System.out.println("==========");
		/**
		 * 1.类Test的main()方法的B.getInstance()生成的invokestatic指令触发了类B的初始化 
			2.执行类B的<clinit>方法的过程中,显式调用了B自己的<init>方法(static b = new B()) 
			3.B的<init>方法中,调用A.getInstance()生成的invokestatic指令触发了A的初始化(private A a = A.getInstance()) 
			4.执行A的<clinit>方法的过程中调用了A自己的<init>方法(static a = new A()) 
			5.类A的<init>方法中需要调用B.getInstance(),但是虚拟机中一个类(<class,classloader>为一个类)只会初始化一次,因此不会再触发B的初始化,既不会再执行B.<clinit>方法。 
			6.那由a.<init>触发的B.getInstance()被执行,输出第一行“B被调用”,B.getInstance()方法结束。虽然这时候B的初始化阶段尚未结束,但是解析阶段已经完成,所以getInstance()方法可以被正确执行,但这时候静态字段static B b仍然为null(注意,b.<init>方法还没完呢),所以这个B.getInstance()方法返回值为null,所以A.b为null。 
			7.A.<clinit>方法结束,第3步的invokestatic指令正式执行,即A.getInstance()被执行,输出第二行“A被调用”,返回A的实例,这时候B.a不为null了。 
			8.B.<clinit>方法结束,第1步的invokestatic指令正式执行,即B.getInstance()被执行,输出第三行“B被调用” 
			9.B.test()方法被执行,输出B.a的toString()方法结果,即第四行“A@35ce36”。 
			10.A.getInstance()方法被执行,输出第五行“A被调用”。 
			11.A.test()方法被执行,输出null,即A.b的值。 
		 */
	}

}

 


http://www.niftyadmin.cn/n/3297995.html

相关文章

Linux CentOS 7 系统配置IP地址新建用户

目录 一、CentOS 7 系统配置IP地址 1、ifconfig 配置IP地址 2、修改配置文件配置IP地址 二、Linux创建用户 1、创建用户 三、wget命令安装 一、CentOS 7 系统配置IP地址 安装完CentOS 7后需要配置IP地址。 1、ifconfig 配置IP地址 该方法是临时配置IP地址&#xff0c;…

URL字符串编码

Server.UrlEncode(s);Server.UrlDecode(s);转载于:https://www.cnblogs.com/ruanbl/archive/2008/12/05/1348189.html

大数据技术-Apache Superset

目录 一、Superset概述 二、安装及使用 1、安装Python环境 2、安装Miniconda 3、创建Python3.8环境 4、Superset部署 5、启动Superset 6、Superset启停脚本 三、Superset使用 1、准备MySQL数据源 2、对接MySQL数据源 3、制作仪表盘 4、调整仪表盘的布局 一、Super…

线上Debug神器--Arthas(阿尔萨斯)

目录 一、Arthas环境准备 1、概述 2、运行环境要求 3、安装&卸载 二、Arthas命令学习 一、Arthas环境准备 1、概述 Arthas是Alibaba开源的Java诊断工具&#xff0c;深受开发者喜爱。 当你遇到以下类似问题而束手无策时&#xff0c;Arthas可以帮助你解决: 1.这个类…

Spring Security二

SpringSide(你可以去官网了解更多信息&#xff0c;我也是从这里开始了解和学习Spring Security的) 前一篇文章里介绍了Spring Security的一些基础知识&#xff0c;相信你对Spring Security的工作流程已经有了一定的了解&#xff0c;如果你同时在读源代码&#xff0c;那你应该…

Idea svn导入maven工程

一、Idea svn导入maven工程 输入svn地址&#xff0c;选择工程目录 checkout前自己点击下图新建文件夹后&#xff0c;选择此文件夹&#xff0c;再进行checkout 二、svn设置需要锁再更改文件 svn--Properties New-->Needs-Lock 设置完成&#xff0c;则需要锁定文件来修改文件…

[Perl]管道、进程及其他

版权声明&#xff1a;可以任意转载&#xff0c;但转载时必须标明原作者charlee、原始链接http://tech.idv2.com/2008/09/04/perl-pipe-process-etc/以及本声明。 昨天一个同事问我关于Perl中的 -| 描述符的问题。他的程序大概是这样的&#xff1a; unless (open FH, "-|&q…

期货

所谓期货&#xff0c;一般指期货合约&#xff0c;就是指由期货交易所统一制定的、规定在将来某一特定的时间和地点交割一定数量标的物的标准化合约。这个标的物&#xff0c;又叫基础资产&#xff0c;对期货合约所对应的现货&#xff0c;可以是某种商品&#xff0c;如铜或原油&a…