昨晚写 深入java虚拟机学习 -- 类的加载机制 都到1点半了,由于第二天还要工作,没有将上篇文章中的demo讲解写出来,今天抽时间补上昨晚的例子讲解。

这里我先把昨天的两份代码贴过来,重新看下:

class Singleton
{private static Singleton singleton = new Singleton(); //第一份代码的位置public static int counter1;public static int counter2=0;private static Singleton singleton = new Singleton();//第二份代码的位置private Singleton(){counter1++;counter2++;}public static Singleton getInstance(){return singleton;}
}public class Demo
{public static void main(String[] args){Singleton singleton=Singleton.getInstance();System.out.println("counter1:"+singleton.counter1);System.out.println("counter2:"+singleton.counter2);}
}

第一份代码执行结果:

第二份代码执行结果:

类是如何被加载的

让我们再来回顾下上篇文章的加载顺序

我们知道Java虚拟机为类的静态变量分配内存,并设置默认的初始值实在准备阶段开始的,这里所设置的初始值通常情况下是类型默认的零值(如0、0L、null、false等),而不是被在Java代码中被显式地赋予的值。有很多人还是不太明白默认零值和显示赋值到底是什么意思,下面我们距离来说:

public class Sample{private static int a=1;private static int b;
}

上面的代码在经过了准备阶段后的结果是:

a=0;
b=0;

大家可能对b=0没有任何疑问,而a=0;就是上面说的“类型默认的零值”,也就是说准备的阶段等号右边的1并不会赋值给a,不知道这么解释大家能不能明白,而类初始化阶段是类加载过程的最后一步,到了初始化阶段,才真正开始执行类中定义的java程序代码。在初始化阶段,Java虚拟机执行类的初始化语句,为类的静态变量 赋予正确的初始值。

private static int a=1; 表示a被显式初始化成1;
private static int b; 这里的b并没有被显式初始化,所以此时b的值仍然为0;

案例分析

好了,说了这么多开始分析案例,我们知道类是自上而下执行的,所以第一份代码解析如下

  1. 当Singletom类在准备阶段,由于只是分配数据类型默认值,所以此时的counter1=0、counter2=0;
  2. 当Singletom类在初始化阶段,1调用了Singleton的实例并对counter1和counter2分别进行了++操作,所以此时的counter1=1,counter2=1,由于2中未对counter1进行显式初始化,所以此时的counter1仍然保留值1,而counter2被显式赋值成0,所以counter2在初始化阶段又被改为0
  3. 在经过了准备、初始化阶段后的最终结果就变成了counter1:1、counter2:0

第二份代码是将1->2->3的顺序修改为2->3->1,我们按着上面的思路重新分析发现很清晰的就知道了结果

准备阶段没有任何变化,counter1=0、counter2=0;

初始化阶段,counter1没有被显式赋值,所以counter1仍然保留值0,counter2被显式赋值为0,所以counter2=0,到第三步时调用了Singleton()方法,此时执行了++操作

最终结果 counter1:1、counter2:1

转载于:https://www.cnblogs.com/blueskyli/p/8487774.html

深入java虚拟机学习 -- 类的加载机制(续)相关推荐

  1. Java虚拟机中 类的加载过程

    Java中 类的加载过程 例如下面的一段简单的代码 public class HelloWorld {public static void main(String[] args) {System.ou ...

  2. Java虚拟机 —— 类的加载机制

    我们知道class文件中存储了类的描述信息和各种细节的数据,在运行Java程序时,虚拟机需要先将类的这些数据加载到内存中,并经过校验.转换.解析和初始化过后,最终形成可以直接使用的Java类型. 类从 ...

  3. 深入理解Java虚拟机:Java类的加载机制

    本篇内容包括:Java 类的加载机制(Jvm 结构组成.Java 类的加载).类的生命周期(加载-验证-准备-解析-初始化-使用-卸载).类加载器 以及 双亲委派模型. 一.Java 类的加载机制 1 ...

  4. 28 Java类的加载机制、什么是类的加载、类的生命周期、加载:查找并加载类的二进制数据、连接、初始化、类加载器、双亲委派模型、自定义类加载器

    28Java类的加载机制 28.1.什么是类的加载 28.2.类的生命周期 28.2.1.加载:查找并加载类的二进制数据 28.2.2.连接 28.2.3.初始化 28.3.类加载器 28.4.类的加 ...

  5. java类验证和装载顺序_Java类的加载机制和双亲委派模型

    Java类的加载机制和双亲委派模型 1类的加载机制 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括了:加载(Loading).验证(Verification).准备(Prepar ...

  6. java 根据类名示例化类_如何使用示例从Java中的类路径加载资源

    java 根据类名示例化类 Java中的类路径不仅用于加载.class文件,而且还可以用于加载资源,例如属性文件,图像,图标,缩略图或任何二进制内容. Java提供了API来将这些资源读取为Input ...

  7. 如何使用示例从Java中的类路径加载资源

    Java中的类路径不仅用于加载.class文件,而且还可以用于加载资源,例如属性文件,图像,图标,缩略图或任何二进制内容. Java提供了API来将这些资源读取为InputStream或URL. 假设 ...

  8. 安卓插件化学习 - 类的加载

    安卓插件化学习 - 类的加载 引言 一.类的加载 1. 原理 2. 代码 2.1 宿主apk代码 2.1.1 插件管理器 2.1.2 配置文件 2.1.3 插件初始化 2.1.4 调用插件方法 2.2 ...

  9. Java内部类以及类的加载顺序(一)

    java内部类以及类的加载顺序(一) Java 类中不仅可以定义变量和方法,还可以定义类,这样定义在类内部的类就被称为内部类.根据定义的方式不同,内部类分为四大类静态内部类,成员内部类,局部内部类,匿 ...

最新文章

  1. 去哪儿app_共享照片APP开发 让出行旅游不留遗憾
  2. jsp中空格字符怎么写_驰骋职场多年,如何对付Excel中的空格字符?
  3. quality center 支持的平台
  4. C#委托Action、ActionT、FuncT、PredicateT
  5. java json格式字符串转为map_json格式的字符串序列化和反序列化的一些高级用法...
  6. 怎么使用java官方demo?
  7. (68)zabbix windows性能计数器使用详解
  8. 伪代码 嵌套循环_大学开始,跟着别人的代码敲对自己编程提高有用吗?
  9. ci php做记录删除,PHP CI APC 使用记录
  10. Java EE开发四大常用框架(1)
  11. 一个Scrapy爬虫实例
  12. 刷手机二维码轻松登机(仅限移动用户)
  13. SolidWorks打开step.文件显示模板无效的解决办法
  14. Java学多久可以接项目_自学Java,多久可以找到工作?
  15. DW与JavaScript
  16. 关于was应用正常,控制台无法连接(SRVE0255E)
  17. awk和sed命令详解
  18. 脂肪体重器、手环、NFC手机
  19. MESH标准配网流程
  20. 合并单元格后怎么拆分单元格(拆分合并后的单元格方法)

热门文章

  1. 斐波那契数列的递归实现
  2. 输入3个字符串,按由小到大顺序输出
  3. /proc文件系统读出来的数据是最新的吗?
  4. Java socket中关闭IO流后,发生什么事?(以关闭输出流为例)
  5. 快速失败(fail-fast)和安全失败(fail-safe)
  6. 日常生活小技巧 -- 网络调试助手
  7. 日常生活小技巧 -- vmware workstation 无法连接到虚拟机
  8. 用CRF做命名实体识别——NER系列(三)
  9. 用 Go 构建一个区块链 -- Part 3: 持久化和命令行接口
  10. GRPC golang版源码分析之客户端(二)