为什么80%的码农都做不了架构师?>>>   

Class类型通常以文件的形式存在(当然,任何二进制流都可以是class类型),只有被java虚拟机装在的class类型才能在程序中使用。系统装载Class类型可以分为加载、连接和初始化3个步骤。其中连接又可分为验证、准备、解析3步。

装载类的条件:

Class只有在必要的时候才会被装载,JVM虚拟机不会无条件地加载Class类型。Java虚拟机规定,一个类或接口在初次使用前,必须要进行初始化。这里指的“使用”,是主动使用、主动使用只有下列几种情况。

1、当创建一个类的实例的时候,new关键字、或者通过反射、克隆、反序列化。

2、当调用类的静态方法时,即当使用了字节码invokestatic指令。

3、当使用类或接口的静态字段时(final常量外)。

4、当使用java.lang.reflect包中的方法反射类的方法时。

5、初始化子类时,要求先初始化父类。

6、作为启动虚拟机,含有main()方法的那个类。

1、

public class Student {

public static String name ="liumou";

static{

System.out.println("student完成装载");

}

}

public class test {

public static void main(String[] args) {

Student student=new Student();

}

}

输出结果是:student完成装载,说明student已经装载完成。

2、删除main中的方法改为

public static void main(String[] args) {

String name=Student.name;

}

输出结果:student完成装载,说明调用类的静态变量可以完成该类的装载。

3、在student类中添加静态变量方法

public static void staticMethod(){

System.out.println("调用了student的静态方法");

}

在test类中用调用staticMethod()方法。

输出结果:student完成装载

调用了student的静态方法

说明:调用类的静态方法是可以完成类的装载。

4、同样是student类,继承Person。

public class Student extends Person{

public final static  String name ="liumou";

static{

System.out.println("student完成装载");

}

public static void staticMethod(){

System.out.println("调用了student的静态方法");

}

public static void main(String[] args) {

System.out.println("student可以被装载");

}

}

public class Person {

static {

System.out.println("父类Person完成装载");

}

public static void methodStatic(){

System.out.println("父类PerSon的方法");

}

}

(1) 在test类中,新建student对象。

输出结果:父类Person完成装载

student完成装载

调用了student的静态方法

结论:对象装载之前需先装载其父类,然后才能装载自己。

(2)在test类中,调用子类调用父类的静态方法methodStatic(),(子类并未覆盖此方法)。

输出结果:父类Person完成装载

父类PerSon的方法

结论:当子类调用父类的静态方法,子类是不会进行装载的。此时的装载,代表的是此时的子类student并未初始化,但是已经被系统加载。使用-XX:+TraceClassLoading可以看日志装载情况。

(3)在test方法中,调用Student的name属性(final修饰的静态变量)。

输出结果:只有“liumou”

结论:说明调用类的final修饰的静态变量不会进行类的装载。此时类连加载都没有。

注:这里说明其他类调用一个类的final修饰的变量时,是不会存在类的加载的,是在编译时直接放在常量池的。     

1、加载类

加载类处于类加载的第一个阶段。在加载类时,Java虚拟机必须完成以下工作:

  • 通过类的全名,获取类的二进制数据流
  • 解析类的二进制数据流为方法区内的数据结构
  • 创建java.lang.Class类的实例,表示该类型

2、验证

  • 2.1、验证类

格式检查

魔数检查

版本检查

长度检查

语义检查

是否继承了final

是否继承了父类

抽象方法是否实现...

字节码验证

跳转指令是否指向正确位置

操作数类型是否合理

符号引用验证

符号引用的直接引用是否存在
  • 2.2、准备

当一个类验证通过时,虚拟机就会进入准备阶段。在这个阶段,虚拟机就会为这个类分配相应的内存空间,并设置初始值。
 int:0

long:0L

short:(short)0

char: \u000

boolean: false

reference: null

float: 0f

double: 0f 
 
 当类中存在常量字段,分情况。在准备阶段,是不会发生字节码行为的。
 public static final String constString ="const";
 当静态变量被final修饰后,该常量 constString在准备阶段被附上字符串"const"
 
 但是如果没有final修饰过,仅仅作为普通变量:
 public static String cString="const"
 此时,   cString的赋值在函数<clinit>中发生,属于java字节码的行为,此时是在初始化中赋值(后面会说到)

  • 2.3、解析类

在准备阶段完成后,进入解析阶段。解析阶段的工作就是讲类、接口、字段和方法的符号引用转化为直接引用。
 符号引用就是字面量的引用。就是在class类文件中,通过常量池进行大量的符号引用。

  • 3、初始化

类的初始化是类的装载的最后一个阶段。如果前面的步骤都没有问题,那么表示类可以顺利的装载到系统中。此时,类才会执行java字节码。初始化阶段的重要是
 执行类的初始化方法<clinit>。方法<clinit>是由编译器自动生成的,他是有类静态成员的赋值语句以及static语句块合并产生的。
 由于加载一个类之前,虚拟机总是试图尝试加载该类的父类,因此父类的<clinit>总是在子类<clinit>之前被调用。也就是说,子类的static块优先级高于父类。
 
 注:classLoader只负责类的加载,连接和初始化与classLoader无关。

转载于:https://my.oschina.net/WEguo/blog/1549255

Java虚拟机之装载(加载、连接、初始化)相关推荐

  1. java加载并运行虚拟机_《深入理解Java虚拟机》- Java虚拟机是如何加载Java类的?...

    Java虚拟机是如何加载Java类的?  这个问题也就是面试常问到的Java类加载机制.在年初面试百战之后,菜鸟喜鹊也是能把这流程倒背如流啊!但是,也只是字面上的背诵,根本就是像上学时背书考试一样. ...

  2. [置顶]类的加载连接初始化

    自己是在看视频的过程中看到一个比较有意思的面试题然后学习了一下关于jvm中类的加载连接和初始化部分的内容,感觉很有收获,所以在博客中记录一下. 首先贴代码: class SingleTon {publ ...

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

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

  4. Java虚拟机是如何加载Java类的?

    前言 从 class 文件到内存中的类,按先后顺序需要经过加载.链接.初始化三大步骤.链接过程需要验证:而内存中的类没有经过初始化,同样不能使用. Java 语言的类型可以分为两大类:基本类型(pri ...

  5. 深入Java虚拟机——类型装载、连接(转)

    来自http://hi.baidu.com/holder/item/c38abf02de14c7d31ff046e0 Java虚拟机通过装载.连接和初始化一个Java类型,使该类型可以被正在运行的Ja ...

  6. java 类 加载 初始化_java类的加载与初始化

    https://blog.csdn.net/u013349237/article/details/71076617 1在命令行启动虚拟机jvm进行加载, 2用class.forname()方法进行动态 ...

  7. java 静态初始化 调用_java JVM-类加载静态初始化块调用顺序

    测试类加载的全过程 public class Have { static { System.out.println("加载Have");//先加载Have再调用main方法 } p ...

  8. java jvm 加载类的顺序_java JVM-类加载静态初始化块调用顺序

    测试类加载的全过程 public class Have { static { System.out.println("加载Have");//先加载Have再调用main方法 } p ...

  9. java的各种加载和初始化的详细过程

    一.什么时候加载和初始化 1.类什么时候加载 类的加载是通过类加载器(Classloader)完成的,它既可以是饿汉式[eagerly load](只要有其它类引用了它就加载)加载类,也可以是懒加载[ ...

  10. Java虚拟机类装载的原理及实现

    Java虚拟机类装载的原理及实现 一.引言 Java虚拟机(JVM)的类装载就是指将包含在类文件中的字节码装载到JVM中, 并使其成为JVM一部分的过程.JVM的类动态装载技 术能够在运行时刻动态地加 ...

最新文章

  1. 网站项目必备——12款白富美型 jQuery 图片轮播插件
  2. Tomcat怎样将配置文件放在外部
  3. 程序员书单_UML篇
  4. mybatis实现分页查询-自己封装分页方法
  5. SEO算法:如何通过PageRank算法判断SEO排序结果
  6. RabbitMQ(4) TopicExchange
  7. 内连接、左外连接、右外连接、交叉连接区别
  8. CODE[VS]1012 最大公约数和最小公倍数问题
  9. Java核心类库——内部类那点事儿
  10. Navicat for my sql 数据结构导出(制作数据字典)
  11. 电容(2)——电容在电路中的作用
  12. GitChat·Python | 零基础小白如何入门 Python 编程
  13. Index || 测试质量分析指标(定量分析+定性分析:T-RCA缺陷根因分析法)
  14. 安徽科技学院 信网学院网络文化节 孙晓楠
  15. numpy 数组扩充维度
  16. JAVA对图片进行等比/非等比压缩处理
  17. 5分钟通俗易懂了解什么是云存储
  18. 【论文笔记】Beyond frontal faces: improving person recognition using multiple cues
  19. android中的ImageView,ImageView加载网络图片
  20. MySQL索引基础续

热门文章

  1. java游戏有个按技能是旋风_快打旋风加难技能增强版
  2. 软件测试开发人员的价值如何体现?
  3. .gitignore文件不生效解决方法
  4. 剑指offer面试题[4]-空格替换
  5. php curl加密获取数据,PHP利用Curl模拟登录并获取数据例子
  6. ❤️不一样的测试之旅:医疗行业软件测试有什么不一样?❤️
  7. PostMan 之 Mock 接口测试
  8. 输入三科成绩 C语言,C语言题,对我的程序找错修改。输入10个学生学号,三科成绩,求总成绩和平均分,并按成绩由高到低输出...
  9. 普通指针到智能指针的转换
  10. 基于阈值和深度学习的玉米常见锈病严重程度自动模糊逻辑预测(工具+综述+玉米锈病严重程度数据集)