java jvm 加载_Jvm是如何加载Java类的?

前言

我们知道Java语言的类型可以分为两大类:基本类型「primitive types」和引用类型「reference types」.

对于Java的基本数据类型是Java虚拟机定义好的.至于另一大类「引用数据类型」, Java将其分为四种类型:类

接口

数组

泛型参数

由于「泛型参数」在编译时期会被擦除, 因此Java虚拟机的类型实际上只有三种.

在类、接口、数组当中,「数组」是由Java虚拟机直接生成的, 类、接口则有对应的「字节流」.

最常见的字节流则属于由Java编译器生成的「class」文件.除此之外我们还可以在程序内部生成、直接从网络当中获取(如applet)的字节流.

这此不同形式的「字节流」都会被加载到Java虚拟机中, 成为类或者接口.

加载过程

从.class文件中的类到内存里的类, 按先后顺序需要经过加载、链接、初始化三个过程.

其中「链接过程」当中还需要进行验证.

内存中的类没有经过初始化,同样是不能能使用.

加载

「查找」是为了查找字节流,并且据此创建类的过程.对于数组来说,是没有字节流的,而是由Java虚拟机直接生成的对于其它类型来说, Java虚拟机则需要借助类加载器来完成查找字节流的的过程.

加载器bootstrapClassLoader(启动类加载器)最顶层的加载器,由c++实现

负责加载%JAVA_HOME%/lib目录下的jar包和类,或者被-Xbootclasspath参数指定的路径中的所有的类.

2. 扩展类加载器「Extension Class Loader」继承于java.lang.ClassLoader

主要负责加载%JAVA_HOME%/lib/ext/下的jar包和类,或者被java.ext.dirs系统变量所指定的路径下的jar包.

3. 应用类加载器「Application Class Loader」继承于java.lang.ClassLoader

面向用户的类加载器

负责加载当前应用classpath下的jar和类.

双亲委派模型双亲委派模型每一个类都有它对应的类加载器.

系统中的ClassLoader在协同的时候会默认启用双亲委派模型.

在类加载的过程中,首先会判断这个类是否被加载过.

被加载过 -> 直接返回

没有被加载过 -> 尝试加载

加载流程先把加载类的请求委派给该父类加载器的loadClass进行处理.

因此所有的请求最终都应该传送到最顶层的类加载器BootstrapClassLoader中.

当父类无法处理时,才需要自己处理.

当父类加载器为null时,会使用BootstrapClassLoader作为其父类加载器

双亲委派模型的优点保证了java的稳定的运行, 可以保证类不被重复加载.

jvm区分不同的类不仅仅是根据全类名, 相同的类文件被不同的类加载器加载产生的也是两个不同的类.

保证java核心api不被修改.

链接

将创建的类合成至Java虚拟机中,使之能够被执行的过程.它可以分为验证、准备及解析三个过程.验证阶段的目的是为了确保被加载的类满足虚拟机的约束条件.

准备阶段的目的是为了被加载类的字段分配内存.

Java代码中对静态字段的具体初始化则会在稍后的初始化阶段进行.

构造其它跟类层次相关的数据结构.比如说用来实现虚方法的动态绑定的方法表.

解析阶段的目的是,将符号引用解析成为实际引用.

如果符号引用指向一个未被加载的类、或者未被加载类的字段或方法,那么解析将触发这个类的加载(但未必触发这个类的链接以及初始化)

初始化

为标记为常量值的字段赋值,以及执行方法的过程.

java虚拟机会通过加锁来确保类的方法仅被执行一次.

只有当初始化完成之后,类才正式成为可执行状态.

类的初始化触发情况当虚拟机启动的时候,初始化用户指定的主类.

当遇到用以新建目标类实例的new指令的时候,初始化new指令的目标类.

当遇到调用静态方法时,初始化该类的静态字段.

当遇到访问静态字段的指令时,初始化该静态字段所在的类.

子类的初始化会触发父类的初始化.

如果一个接口定义default方法,那么直接实现或者间接实现该接口的类的初始化,会触发该接口的初始化.

使用反射api对某个类进行反射调用时,初始化这个类.

当初次调用MethodHandle实例时,初始化该MethodHandle指向的方法所在的类.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/550829.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python查找文件内容_python自定义查找文件内容

#!/usr/bin/env python#coding:utf8#此脚本为查找递归目录下所有文件匹配的内容import os,sys,tabdef paths(path):list_pathos.walk(path)all_file[]for p,d,fl in list_path:for f in fl:pfileos.path.join(p,f)if os.path.isdir(pfile):paths(pfile)all_file.append(pfile)r…

derby mysql 同步_[Derby]数据库操作说明

1. 创建新数据库connect jdbc:derby:mydb;createtrue;ij> connect jdbc:derby:mydb;createtrue;ij>将在当前目录下建立数据库目录 mydb;如果已经存在数据库 mydb,则提示:警告 01J01:未创建数据库"mydb",而是建立到现有数据库…

lfu算法实现java_LFU五种实现方式,从简单到复杂

前言最近刷力扣题,对于我这种 0 基础来说,真的是脑壳疼啊。这个月我估计都是中等和困难题,没有简单题了。幸好,力扣上有各种大牛给写题解。看着他们行云流水的代码,真的是羡慕不已。让我印象最深刻的就是人称 “甜姨”…

java控制台高级_K9s Kubernetes的高级控制台

K9s Kubernetes CLI,以个性化方式管理您的集群!参考:Why K9s?首先我们得面对现实——Kubernetes及其周边生态系统的运营方式正变得越来越复杂。集群管理需要大量工具加以配合。当我在集群之上进行日常运营时,和大家一样…

java redis id生成器_基于redis的分布式ID生成器

项目地址基于redis的分布式ID生成器。准备首先,要知道redis的EVAL,EVALSHA命令:原理利用redis的lua脚本执行功能,在每个节点上通过lua脚本生成唯一ID。生成的ID是64位的:使用41 bit来存放时间,精确到毫秒&a…

Java自动切表_java_Mybatis自动创建表和更新表结构,最近有小伙伴问我mybatis有没有 - phpStudy...

Mybatis自动创建表和更新表结构最近有小伙伴问我mybatis有没有自动创建表结构的功能,因为他们之前一直使用hibernate用习惯了,理所当然的认为,在实体类上配置下注解或者写写映射文件,系统启动后就可以自动创建表。我只能很遗憾的告…

java byte 正数最大_关于JAVA中Byte类型的取值范围的推论(*零为正数,-128在计算机中的表示方法...)...

先看一段推理124:0111 1100  -124:1000 0100125:0111 1101  -125:1000 0011126:0111 1110  -126:1000 0010127:0111 1111  -127:1000 0001128:0 1000 0000 -128:1000 0000从上述过程对比可以看出:128是在127的基础上加1得到,但是会造成溢出(java中byte的大小为一个字…

java不同类间调用数组_请问:JAVA中两个类中的方法都需要调用另一个类的数组进行对数组的初始化和调用。...

匿名用户1级2013-09-14 回答import java.util.ArrayList;import java.util.Iterator;import java.util.List;/*** 测试类* author Administrator**/public class Test02 {public static void main(String[] args) {MovieStore movieStore new MovieStore();DVDManage.initDVD(…

java函数只有参数类不一样_java的函数参数传递

java中只有一种参数传递方式:传值;这点和c不一样,c中有传值和引用两种方式。虽然java只有传值这一种传递方式,但是根据参数类型的不同,函数对参数的影响也会不一样。可以这么说:形参是实参的一份拷贝&#…

java缓存回收_java缓存应用 - 阿亮ing的个人空间 - OSCHINA - 中文开源技术交流社区...

缓存回收策略1.基于空间设置缓存的存储空间,超过容量限制按照一定的规则去移除。2.基于容量当缓存条数超过规定容量按照一定的规则去移除旧数据。3.基于时间(存活时间空闲时间)TTl(Time To Live):存活期,缓存数据最后更新时间到指定时间如果没有更新或创…

java mvc中重复提交_SpringMVC之——防止重复提交表单的方法(一)

这篇博文介绍第一种方法:判断session或其他缓存中保存的token,这里以session为例,具体大家也可以自行扩展以其他的缓存实现。这种方式比较麻烦,每次在提交表单时都必须传入上次的token。而且当一个页面使用ajax时,多个…

三层加过的注释java_spring框架中三层架构相关的注解

做了这么多年的C,再去学Java,确实发现,语言都是相通的,即使是Java的那么多生态,理解起来也并不费劲Spring 框架目前还在学习中,处于 Tourist 阶段,目前只求会做,不求原理&#xff0c…

尤其是java程序员(转载)_JAVA程序员 学习任务(转载)

1. 你需要精通面向对象分析与设计(OOA/OOD)、涉及模式(GOF,J2EEDP)以及综合模式。你应该了解UML,尤其是class、object、interaction以及statediagrams。2. 你需要学习Java语言的基础知识以及它的核心类库(collections、serialization、streams、networki…

java setfilter_Java – setFileFilter问题

我正在JFileChooser上构建一个JFileFilter,但是如果我有代码setFileFilter并且我的IDE提供了信息’JFileChooser类型中的方法setFileFilter(FileFilter)不适用于参数(new FileFilter(){},则会发生错误)”.不过我确信我之前已经用这种格式完成了它并且一切都很好.任何人都可以帮…

mysql指南_MySQL入门指南

MySQL入门指南,希望对大家用处!!一、SQL速成以下是一些重要的SQL快速参考,有关SQL的语法和在标准SQL上增加的特性,请查询MySQL手册。1.创建表表是数据库的最基本元素之一,表与表之间可以相互独立&#xff0…

java单线程上锁_关于Java多线程编程锁优化的深入学习

正文并发环境下进行编程时,需要使用锁机制来同步多线程间的操作,保证共享资源的互斥访问。加锁会带来性能上的损坏,似乎是众所周知的事情。然而,加锁本身不会带来多少的性能消耗,性能主要是在线程的获取锁的过程。如果…

java test circle_TestCircle.java

import java.util.Scanner;public class TestCircle {public static void main(String[] args) {// TODO Auto-generated method stubScanner sc new Scanner(System.in);/*Circle c1 new Circle();System.out.print("第一个圆已经生成, 它的半径是:");System.out.…

蓝桥杯小朋友排队java_[蓝桥杯][历届试题]小朋友排队 (C++代码)

#include#define maxn 100010struct data{int num,cnt;}A[maxn],temp[maxn];int n;//long long ans;long long ANS[100];void merge(int L1,int R1,int L2,int R2){int k0,iL1,jL2;while(i<R1 && j<R2){if(A[i].num<A[j].num)//如果A[i].num{A[i].cntj-L2;tem…

android 换行乱_Android自动换行布局

public class FlowLayout extends ViewGroup {/*** 所有子控件的容器*/private List> lineList new ArrayList<>();/*** 每行的高度*/private List lineHeightList new ArrayList<>();/*** 防止多次测量*/private boolean measureFlag true;public FlowLayou…

php数组常用_PHP常用数组总结

header("Content-type:text/html;charsetutf8");//1. array_shift&#xff1a;将数组开头的元素移出数组 出栈 影响原数组$arrarray(1,2,3,4,5,6,7,8,9);echo array_shift($arr);echo "";//2. array_unshift&#xff1a;向数组开头添加一个或更多个元素,所…