Java类加载过程
Java类是如何编译以及加载到Java虚拟机中呢?看下图所示,简要概括了整个相关流程:
1。编译
在Java技术中,有下面三种类型的编译器:
前端编译器:把。java文件转变成。class文件。代表性的产品有JDK的Javac、EclipseJDT中的增量式编译器(ECJ)。
即时编译器:通常称为JIT编译器(JustInTimeCompiler),运行期把字节码转变成本地机器码。代表产品有HotSpot虚拟机的C1、C2编译器,Graal编译器。
提前编译器:通常称为AOT编译器(AheadOfTimeCompiler),直接把程序编译成与目标机器指令集相关的二进制代码。代表产品有JDK的Jaotc、GNUCompilerfortheJava(GCJ)、ExcelsiorJET。
其中,最符合我们对Java程序编译认知的是前端编译器,也是本文要重点介绍的。
词法、语法分析
词法分析是将源代码的字符转变为标记(Token)集合的过程,单个字符是代码源文件编写时的最小元素,但标记才是编译时的最小元素。关键字、变量名、字面量、运算符都可以作为标记。如intxy1这句代码中就包含了6个标记,分别是int、x、、y、、1,虽然关键字int由3个字符组成,但它是一个独立的标记,不可再拆分。词法分析过程由com。sun。tools。javac。parser。Scanner类来实现。
语法分析是根据标记序列构造抽象语法树的过程,抽象语法树(AbstractSyntaxTree,AST)是一种用来描述程序代码语法结构的树形表示方式,抽象语法树的每一个节点都代表着程序代码中的一个语法结构,例如包、类型、修饰符、运算符、接口、返回值,甚至代码注释都可以是一种特定的语法结构。语法分析过程由com。sun。tools。javac。parser。Parser类实现,构造出的抽象语法树以com。sun。tools。javac。tree。JCTree类表示。
注解处理器
JDK5之后,Java语言提供了对注解(Annotations)的支持。原本设计上,注解与普通Java代码一样,都只会在程序运行期间发挥作用,但在JDK6又提出并设计了一组被称为插入式注解处理器的标准API,可以提前至编译期对代码中的特定注解进行处理,从而影响到前端编译器的工作过程。开发人员能使用插入式注解处理器来实现许多原本只能在编码中由人工完成的事情。比如我们常用的Lombok,它可以通过注解来实现自动产生gettersetter方法等等,帮助我们提升开发效率并消除冗长的Java代码。
语义分析
经过语法分析之后,编译器获得了程序代码的抽象语法树表示,抽象语法树能够表示一个结构正确的源程序,但无法保证源程序的语义是符合逻辑的。所以,语义分析的主要任务是对结构上正确的源程序进行上下文相关的检查,比如类型检查、控制流检查等等。我们编写代码时,在IDE中看到的由红线标注的错误提示,绝大部分都是来源于语义分析阶段的检查结果。
字节码生成
字节码生成是Javac编译过程的最后一个阶段,由com。sun。tools。javac。jvm。Gen类来完成。字节码生成阶段不仅仅是把前面各个步骤所生成的信息转化成字节码指令写到磁盘中,编译器还进行了少量的代码添加和转换工作,如添加默认构造函数、把字符串的操作替换为StringBuffer或StringBuilder的append()操作等等。最终,生成class文件,编译过程结束。
即时编译(JIT,JustInTimeCompiler)
在程序执行过程中能够随着程序的需要生成并执行新的代码即称为即时编译。在目前大多数虚拟机里面都实现了JIT即时编译技术。虽然Java虚拟机规范并没有明确指出必须实现它,但是JIT编译性能、代码优化程度却是衡量一款虚拟机最关键的指标之一。
2。加载
类加载器完成类的加载,主要包括三部分工作:获取class字节码文件二进制字节流将文件静态结构载入内存方法区转化为运行时数据结构,即类信息将载入后的类信息进行组装,在堆空间中生成类对象
类加载器
JVM预定义了三种类型类加载器:
BootstrapClassloader(启动类加载器):是用本地代码实现的类装入器,它负责将
jrelib下面的类库加载到内存中(比如rt。jar)。由于引导类加载器涉及到虚拟机本地实现细节,开发者无法直接获取到启动类加载器的引用,所以不允许直接通过引用进行操作。
ExtensionClassloader(标准扩展类加载器):是由sun。misc。LauncherExtClassLoader实现的。它负责将jrelibext目录或者由系统变量java。ext。dirs指定位置中的类库加载到内存中。开发者可以直接使用标准扩展类加载器。
SystemClassloader(系统类加载器):是由sun。misc。LauncherAppClassLoader实现的。它负责将系统类路径(CLASSPATH)中指定的类库加载到内存中。开发者可以直接使用系统类加载器。
双亲委派
当前类加载器需要加载某个类时不会自己直接去加载,而是尝试将加载这个类的任务向上传递交给父加载器去完成,如果父类加载器能加载则由父类加载器来完成而自己不会再去加载。双亲委派模式的具体工作过程如下:
当SystemClassLoader收到一个类加载请求时,他首先不会自己去尝试加载这个类,而是将这个请求委派给父类加载器ExtensionClassLoader去完成。
当ExtensionClassLoader收到一个类加载请求时,他首先也不会自己去尝试加载这个类,而是将请求委派给父类加载器BootstrapClassLoader去完成。
如果BootstrapClassLoader加载失败(在lib中未找到所需类),就会让ExtensionClassLoader尝试加载。
如果ExtensionClassLoader也加载失败,就会使用SystemClassLoader加载。
如果SystemClassLoader也加载失败,就会使用自定义加载器(UserClassloader)去尝试加载。
一个简单示意图,有助于理解:
双亲委派模式优点避免重复加载
Java类随着它的类加载器一起具备了一种带有优先级的层次关系,通过这种层级关系可以避免类的重复加载,当父亲已经加载了该类时,子ClassLoader就没有机会加载。
避免JDK核心类被篡改
考虑这样一个问题:能不能自己写个类叫java。lang。System?
答案:JDK中的System核心类是Bootstrap加载器加载的,就算自己重写,当加载自定义的System类时,通过双亲委托模式传递到Bootstrap加载器,Bootstrap加载器发现该类已被加载,所以并不会再次加载自定义的System类,总是使用JDK自带的System类,自己写的System类根本没有机会被加载。这样可以防止JDK核心类被随意篡改。
显式加载与隐式加载
显式加载:程序主动调用下列方法之一去主动加载一个类classloader。loadClass(className)Class。forName(className)
隐式加载:被显式加载的类对其它类可能存在如下引用继承(extend)实现接口(implements)域变量方法定义方法中定义的本地变量
被引用的类会被动地一并加载到JVM,这种加载方式属于隐式加载。
2022(阳城)首届山西森林旅游节开幕陈河波摄黄河新闻网晋城讯(记者尚东霞)寻梦森林之旅,绿染康养濩泽。9月20日,2022(阳城)首届山西森林旅游节在山西省晋城市阳城县正式拉开帷幕。来自全国各地的嘉宾相聚在……
8点1氪义乌市监局回应下架槟榔百度糯米App已从应用商店下架上市进行时申万宏源36氪获悉,申万宏源公告称,近日,公司所属全资子公司申万宏源证券收到中国证监会的批复,根据该批复,中国证监会核准申万宏源证券上市证券做市交易业务资……
游遍名山大河,走进祖国各地作者张德富游遍名山大河,走进祖国各地作者绿野(1)记忆犹新的怀念,是我历历历在目,游荡在外,每时每刻,激荡着我的心花怒放,难能可贵的温馨,靠韧劲一遍一遍游走祖国,感动自……
太极拳练的好不好?看眉宇间就知道眉宇间的放松,是人在练太极拳过程中能够看得见、感觉得到的一个现象。它既是习拳的内在要领,更是身、心、息整体进入练拳状态的一种外在表现。放松体感、意感以及气息的感觉无不体现在眉宇……
去饭店吃饭时,聪明人从不点这4道菜,老板反正我是不会吃去饭店吃饭时,聪明人从不点这4道菜,老板:反正我是不会吃!俗话说得好民以食为天,食物是人们赖以生存的根本之一,一日三餐可以说是顿顿都不能少,甚至亲朋好友之间在见面时,互相……
孩子爱不爱你,从家长这几件事可以看出一切,不妨对照下我们都当过小孩子,也是在长大后即将为人父母的今天,我们才知道父母的不容易。也才更深刻明白昔日父母对我们悉心教导、严厉要求的苦心,相比较于身边一些同龄人,也才更懂得来自父母的家庭……
土超豪门冬窗签C罗?曼联回应太扎心豪门里没人想要他日前,有土耳其媒体报道称,土超豪门加拉塔萨雷希望在冬季转会窗签下C罗,后者从今年夏天就一直寻求离队,虽然暂时留在曼联,但葡萄牙人并非球队主力,他仍希望冬季转会窗可以离开。……
高平全力打造不锈钢全产业链强化企业链主作用培育壮大优势产业集群国庆长假期间,在高平市不锈钢制品产业园项目施工现场,塔吊林立、机器轰鸣,大型机械来回穿梭,工人师傅奋战正酣,铆足干劲刷新项目建设进度条……
炎炎夏日优调给您带来夏日凉拖推荐随着生活水平日趋提升,促使大家越来越重视生活质量与舒适感。都市丽人们早已不再执着于高跟鞋所带来的优雅精致,而更注重穿着体验上的肆意休闲。最近天气一天比一天热,每天出门迎面就是一……
出彩自己,不枉此生三行情诗挑战我记得十七岁的时候在县报发表了第一首诗歌!(拖着长长的情思,像是身边的影子,又似远我而的白云。自古苦难的人生,谁没有过无名的等待?痛苦和幸福,我们只能得到一份!后来……
海伦弗拉纳根脱下无肩带黑色内衣,展示她令人难以置信的身材这位前加冕街明星用她最新的Instagram视频让粉丝们为之疯狂,视频中可以看到她穿着内衣摆姿势,并塑造性感的红地毯造型这位32岁的女士穿着轻薄的黑色内衣展示了她令人难以……
秋季是吃鱼黄金季,多吃八种鱼类美食,开胃营养,强身健体身体好大家好,这里是邱哥说美食,进入秋天后,江河湖泊的鱼类陆续变得越来越肥美,因而,秋天是捕鱼的黄金季节,也是吃鱼的黄金季节。所以,建议朋友们这段时间可以多吃鱼,鱼肉含有特别丰富的维……