编写的java文件在要真正运行时,会首先被编译成 “.class"结尾的二进制文件,然后被虚拟机加载。那么在虚拟机中一个class文件要成为java实例,需要经历好几个步骤:

1、装载:装载阶段由三个基本动作完成,要装载一个类型,java虚拟机必须:

(1)通过该类型的完全限定名,产生一个代表该类型的二进制数据流

(2)解析这个二进制数据流为方法区内的内部数据结构

(3)创建一个表示该类型的java.lang.Class的实例

***当时用new关键字创建一个对象时,该类的数据结构存放在方法区中,new出的对象存放在堆中

二进制的数据流可由以下方式产生:

1、从本地加载一个java class 文件

2、通过网络上下载一个class文件

3、从一个zip、jar、或者其他文档中提取class文件 等…

2、验证:类被装载后,就要准备连接,连接的第一步是验证——确认类型符合java语言规范,并且不会危及虚拟机的完整性。

类型的检查——确保除了Object之外的每个类都必须有一个超类,并确保该类的所有超类都已经被装载了

类之间的二进制兼容检查——检查final类不能用于子类、检查final类的方法不能被覆盖、确保子类和超类之间没有不兼容的方法

——检查所有的常量池入口相互之间一致

——检查常量池中的所有特殊字符串是否符合格式

——检查字节码的完整性(最为复杂的一步)

3、准备:在准备阶段java虚拟机为类变量分配内存,设置默认初始值,但在到达初始化之前,类变量都没有被初始化为真正的初始值。即:我们在类中声明 int a = 3;但在这一步,a的致被赋予类型的默认值 0 int a =0;java虚拟机不支持boolean 类型,在内部,boolean变量会被默认的设置为int类型的0,即初始化成false.

4、解析:经过验证和准备之后,就进入了解析过程。解析就是在类型的常量池中寻找类、接口、字段、以及方法的符号引用,把这些引用替换成为直接引用的过程

5、初始化:初始化就是赋予一个变量真正的初始值

如我们定义 private static int a=1; 此时就是给a赋值1

二、动态链接和解析

class文件把所有的符号引用保存在——常量池中,每一个 class文件都有一个常量池。每一个被虚拟机装载类或者接口 都有一个内部版本的常量池,被称为运行时常量池。

常量池的解析——当程序运行时,某个特定的符号引用要被使用, 首先要被解析。解析过程就是根据 符号引用查找到实体, 在把符号引用替换成为 直接引用的过程。每个符号引用都只被解析一次

早解析——预先解析所有的符号引用,从初始类开始,到后续的各个类,知道所有的符号引用都被解析。

迟解析——在访问每一个符号引用的最后一刻才去解析。(也可选择两种情况之间的折衷策略)

——程序执行都是在第一次 实际访问一个符号引用时才会抛出错误,对于用户来说,看上去都是 迟解析

——java虚拟机会把所有具有相同字符串顺序的字符串文字处理成一个String对象。即:如果有多个类使用同一个字符串“Hello”,java虚拟机只会创建一个具有“Hello ”值的String对象 来表示所有的字符串文字。

——任何的byte、short、char的值在被压入栈中时, 都会先被转换成int型

——涉及byte、short、char的运算操作会首先把他们都转换成int类型,进行计算然后得到int结果,如果需要byte等结果,需要进行显示转换。

——java虚拟机中内存只能以对象形式在堆中进行分配,如果需要可考虑基本类型包装器

——java所使用的同步机制是监视器,java中的监视器支持两种线程:互斥和协作。java虚拟机是通过锁来实现互斥,是通过Object的wait和notify方法来实现协作

——只有当绝对确定等待区中只有一个线程挂起的时候才应使用notify,只要存在同时有多个线程挂起的可能性,就应该使用notify all。否则可能导致某个特定的线程在等待区中等待时间过长,甚至永远就不会苏醒。

——堆和方法区是被所有线程共享的

——会被多线程访问的两种数据:保存在堆中的实例变量,保存在方法区中的类变量

——不需要进行保护的变量:java栈中的局部变量,该数据是拥有该线程的线程私有的

——当虚拟机装载一个class文件的时候,会创建一个java.lang.Class类的实例。当锁住一个类的时候,其实就是锁住那个类的Class对象。

jvm内置的三大类加载器

BootStrap类加载器(BootStrapClassLoader):根类加载器。该加载器没有父加载器,负责加载虚拟机的核心类库,如:java.lang.*等,java.lang.Object就是由根加载器加载的

Extension 类加载器(ExtClassLoader):它的父加载器为根加载器,也就是上面那个。它从java.ext.dirs系统属性所指定的目录中加载类库,或者从jdk的安装目录jre/lib/ext子目录中加载类库。该类是纯java类是lava.lang.ClassLoader类的子类

System系统类加载器(AppClassLoader),也称为应用类加载器,其父加载器为扩展类加载器,上面那个。它从环境变量classpath中多指定的目录中加载。它是用户自定义类加载器的默认父加载器,该类是纯java类是lava.lang.ClassLoader类的子类

**注意:使用Class.forName("com.test.Test1")进行类装载时,会自动执行类中的静态代码块,但不会执行构造方法

使用loadClass("com.test.Test1")进行装载时,不会自动执行其中的静态代码块,也不会执行构造方法

***:同一个类,由两个不同的类加载器去加载,会被认为是两个不相同的类,在方法区中会有两份该类的类信息

只有使用启动类加载器加载的类,比如:java.lang.Strong、java.lang.Object 等类,在方法区中只有一份类信息。

判断两个类是否相等的基础是,这两个类的类加载器是不是同一个

初始化:对于类的初始化阶段,虚拟机规范规定了5种情况下必须立即对类进行初始化

1、遇到new、getstatic、putstatic、invokestatic这四条字节码指令时,如果类之前没有进行过初始化会进行初始化。这四条字节码对应的是:new 实例、静态字段取值、静态字段赋值、静态字段调用。

2、使用java.lang.refleat包的方法进行反射调用

3、当初始化一个类时,如果发现其父类还没有被初始化,需要先初始化其父类

4、当虚拟机启动,需要执行main方法的类

5、当使用LDK1.7的动态预言支持时,如果一个java.lang.invole.MethodHandle实例的最后解析结果是REF_getStatic,REF_putStatic,REF_invokeStatic的方法句柄。

以下几种情况需要注意:

1、对于静态字段,只有直接定义这个字段的类或者接口才会被初始化,如果是通过子类引用父类中的静态字段,只会触发父类的初始化。

2、常量在编译阶段会存入调用类的常量池中,本质上并没有直接引用到定义类的常量,因此不会触发定义常量的类的初始化。备注:只有编译器能确定之的常量才会进行该操作,编译器无法确定的常量值,还是会触发目标类的初始化。

例如:public static final String uuid = UUID.randomUUID().toString(); 这行代码,当其他类在引用uuid时,会触发定义该uuid的类的初始化

3、通过数组定义来引用类,不会触发类的初始化 例如: Super[ ] s = new Super[10]; 这行代码并不会触发Super类的初始化

4、当一个接口初始化的时候,并不要求其父接口也被初始化,只有真正使用到父接口的时候才会初始化。

私信我获取更多JAVA学习资料!

————————————————

本文转载至CSDN——终南山_半仙,如有侵权请联系立删!

原文链接:https://blog.csdn.net/qq_37150258/article/details/83505011

在类中用class时数据是共有还是私有_jvm学习笔记之class文件的加载、初始化相关推荐

  1. 在类中用class时数据是共有还是私有_C++判断题题库1

    序号 题干 答案 5 使用关键字 class 定义的类中默认的访问权限是私有 (private) 的 . 对 6 作用域运算符 (::) 只能用来限定成员函数所属的类 . 错 7 构造函数和析构函数都 ...

  2. 《R数据可视化手册》一1.4 从Excel文件中加载数据

    本节书摘来自异步社区<R数据可视化手册>一书中的第1章,第1.4节,作者 [美]Winston Chang,更多章节内容可以访问云栖社区"异步社区"公众号查看 1.4 ...

  3. python 异步加载_Python学习笔记4——爬取异步加载数据

    一.什么是异步加载? 在之前的学习笔记中,爬取的网页是需要手动翻页的网址,但是一些网站是通过自动加载翻页的,如knewone网页.浏览knewone的官网就能发现,当下拉到网页最下端时,网站会自动加载 ...

  4. 『ML』利用K-Means聚类算法对未标注数据分组——《机器学习实战》学习笔记(Ch10)

    本节用Python实现K-Means算法,对未标注的数据进行聚类. 在做完聚类后,如何对于聚类结果进行评估?请看 用Python实现聚类效果的评估(轮廓系数.互信息) 导航 K-Means简介 代码实 ...

  5. 2021年大数据HBase(十五):HBase的Bulk Load批量加载操作

    全网最详细的大数据HBase文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 系列历史文章 HBase的Bulk Load批量加载操作 一.Bulk L ...

  6. Matlab绘图保存为.fig格式以使用,及.fig文件的加载与数据读取

    1 使用背景 fig文件作为Matlab中的图形文件,其实原始数据是会存储在figure对象中的,其不仅仅只是一张图片: 论文写作时,直接将plot运行的结果进行截图粘贴时,图片的分辨率不够导致曲线及 ...

  7. Pandas将dataframe保存为pickle文件并加载保存后的pickle文件查看dataframe数据实战

    Pandas将dataframe保存为pickle文件并加载保存后的pickle文件查看dataframe数据实战 目录 Pandas将dataframe保存为pickle文件并加载保存后的pickl ...

  8. Python时间序列模型推理预测实战:时序推理数据预处理(特征生成、lstm输入结构组织)、模型加载、模型预测结果保存、条件判断模型循环运行

    Python时间序列模型推理预测实战:时序推理数据预处理(特征生成.lstm输入结构组织).模型加载.模型预测结果保存.条件判断模型循环运行 目录

  9. 在Spring Boot中加载初始化数据

    文章目录 依赖条件 data.sql文件 schema.sql 文件 @sql注解 @SqlConfig 注解 在Spring Boot中加载初始化数据 在Spring Boot中,Spring Bo ...

最新文章

  1. 关于软件开发你真正需要知道的几个事情
  2. 阿里转衰!百度没落!字节跳动崛起!未来的互联网是腾讯和字节跳动的世界!这样的言论你相信吗?...
  3. pandas loc iloc(self index location 即按照行索引来获取数据)
  4. 2018年科技公司融资纪录十大排行榜!中国四家公司上榜
  5. IE常见的CSS的BUG(一)
  6. OpenGL的glScissor示例程序
  7. 我在项目中运用 IOC(依赖注入)--入门篇
  8. CF468A 24 Game
  9. Python渗透测试之身份认证攻击
  10. Snipaste贴图软件使用方法及快捷键
  11. 一文带你玩转 DataStore
  12. 面试非重复数字的全排列
  13. chrome调试工具使用技巧汇总
  14. myeclipse 百度云
  15. 试着用人话说说 使命 愿景 价值观,以及人的三观
  16. pandas常用操作
  17. 2021-11-10
  18. 是——我说明白了么?而不是——你听懂了么?
  19. win32con模块安装
  20. 计算机软件故障的排除方法,Windows 7系统常见小故障以及排除方法

热门文章

  1. ActionScript 3.0 Step By Step系列(四):来自面向对象开发之前的呐喊:“学会写可重用的代码”...
  2. 35岁前把下面十件事做好
  3. jps: command not found
  4. linux内存管理简介,Linux操作系统的内存管理特性简介 (3)
  5. stract oracle,ORACLE 字符串聚合函数 strCat
  6. 如何让自己的写的程序在阿里云一直运行
  7. 2021年广西高考成绩查询方法,2021年广西高考成绩查询网站查分网址:https://www.gxeea.cn/...
  8. bootstraptable获得所有行_郎酒领衔,2020“川酒全国行”首站香满花城
  9. RedisTemplate中opsForValue()中的方法
  10. 开发工具:Git超全实用技巧,值得收藏!