当前位置: 首页 > wzjs >正文

网站开发和网页制作宁德市公共资源交易中心

网站开发和网页制作,宁德市公共资源交易中心,贵阳网站制作 建设,西地那非最佳起效时间Java源码的前端编译 欢迎来到我的博客:TWind的博客 我的CSDN::Thanwind-CSDN博客 我的掘金:Thanwinde 的个人主页 0.前言 当一份Java代码写好时,将其进行编译,运行,并不是简单把这个Java源码从头到尾执行…

Java源码的前端编译


欢迎来到我的博客:TWind的博客

我的CSDN::Thanwind-CSDN博客

我的掘金:Thanwinde 的个人主页


0.前言

当一份Java代码写好时,将其进行编译,运行,并不是简单把这个Java源码从头到尾执行,一般来说会经历前端编译和后端编译两个阶段,前端编译会把Java源码进行分析,拆解,填充并进行一些优化来变成字节码

后端编译是发生在JVM已经在解释执行字节码时的JIT,会进行一些分析来将热点代码直接替换成大部分情况下效率更高的本地机器码,并进行许多优化,从而提高效率

除去前后编译,还有提前编译,后面都会写文章一一介绍


1.前端编译阶段

前端编译是一个Java源码的开始,在这里会将其转化为可以执行(效率不谈)的字节码

Javac

Javac是收录于JDK中的Java编译器。该工具可以将后缀名为.java的源文件编译为后缀名为.class的可以运行于JVM的字节码,Javac是由Java写的,运行javac的实质便是命令行的调用:javac hello.java

Java对于如何把.java文件转化为.class文件规范得很宽松,可能会导致class在一些JDK上能编译,一些却不行的情况

具体来说,Javac的编译过程可分为四个阶段

  • 初始化插入式注解处理器
  • 解析与填充符号表
    • 把源代码转化为标记集合来构造抽象语法树
    • 填充符号表
  • 注解处理器处理注解
  • 语义分析与生成字节码
    • 标注检查
    • 数据流与控制流分析
    • 解语法糖
    • 字节码生成

下面,让我们一个个来看:


初始化插入式注解处理器

JDK5之后,Java提供了对注解的支持,原本的方案是把注解作为运行时才发挥作用的,但是到了JDK6,引入了插入式注解处理器:让注解处理可以发生在编译阶段,一般来说,运行时的注解只能完成一些反射,自动化类的操作,但注解处理时可以动态的向其中加入代码:譬如lombok之类的动态生成代码,使注解能在代码层面影响代码

SPI

许多的框架其实都是依靠于这套机制完成的,而这些是基于一种名为 SPI 的技术

和SPI对应的是API,API(Application Programming Interface)

在这里插入图片描述

API就是上方:实现方已经实现了接口,要求调用方去实现它

SPI反过来:接口由调用方决定,实现方要根据调用方的接口要求去实现这个接口来提供服务

API最典型的实现就是OAuth2服务:你需要按照OAuth2提供商的要求去实现登录过程

SPI最典型的也就是JDBC,日志:各种数据库的JDBC驱动都是按照统一的接口规范来编写的,完全符合调用者制定的规范,众多的日志实现类也同理

但这只是SPI的概念,和Java中修改源代码的需求好像并无交集

具体来说,Java设计了许多接口,来供其他包作者去适配

这其中就包括注解的解释接口:javax.annotation.processing.AbstractProcessor,或是javax.annotation.processing.Processor(插入式注解处理器会放在META-INF/services之中)

在编译的时候,也就是一开始编译,Javac会先加载所有实现了这个接口的类,也就是所有插入式注解处理器(包括你自定义的),这实际上破坏了双亲委派模型

在这里插入图片描述

因为对于javac(对一般的java程序也一样)来说,这些插入式注解处理的实现(SPI)都属于“应用程序级”的,应该由最低级的应用程序类加载器加载

但实际上,他们的接口都位于“高层”,其接口是由启动类加载器加载的,但是这些高层的接口要去加载自己的实现类,就属于高级类加载器加载低级类加载器了

这里,java引入了线程上下文类加载器,这个加载器可以跨界进行加载,这样就能帮助高层的加载器加载底层的类

至于这里为什么强调“线程上下文”,我们可以以tomcat举例:通常里面有多个线程来处理请求,相互应该隔离:对于java,不同类加载器加载的同一个类,视为不同类,不相同也不兼容,这样就能隔离开不同线程

也不用担心每个线程都要去加载一个SPI,只会进行一次类加载,剩下的都会从缓存之中直接加载,尽管是其他线程

总而言之

通过SPI,我们就能解决Javac在准备编译时去加载插入式注解处理器的问题了


解析与填充符号表

词法语法分析

这里会把代码中的字符流转化为标记(Token),Token是编译时的最小元素,比如int a = b + 2,会拆分成6个Token:int ,a,=,b,+,2

接着会把这些Token按照顺序构造成抽象语法树(AST),其代表了一个程序的语法结构,你可以理解为是一个能保存一个程序的所有信息的数据结构

之后,Javac就不会再操作字符流了,一切都会围绕着语法树来进行

填充符号表

符号表类似于一个哈希表,用来标识每一个符号的地址和其信息,用人话来说的话,就是会标记一些Token,记录下这些Token的名字,类型,作用域等等,譬如方法名,变量名这类的,会用来进行各种检测,优化:比如语法检查,分配地址子类的,符号表就像是电话簿一样的角色


注解处理器处理注解

这里相对的简单:会调用每一个注解处理器进行处理,如果其对语法树进行了更改:就会回退到解析与填充符号表 重新处理,因为可能改变了语法以及符号表,这个操作称之为轮(Round),可以抽象成下面这个图

在这里插入图片描述

当所有注解处理器都处理完成后,便会进入下一个阶段:


语义分析与生成字节码

这里已经具有了一个完整的语法树和符号表,最后一步就是把这些转化成字节码了

标注检查

这里会进行类型赋值是否互相兼容,变量使用前是否声明,还会进行常量折叠,这是前端编译中为数不多的优化:int a = 1 + 2,这里会把1 + 2 在语法树上直接变成3

数据及控制流分析

这里会对各种逻辑进行进一步的验证,比如,对于局部变量用之前有无赋值,是否有返回值,异常是否会处理这种更复杂的控制

值得注意的是,这里的分析是和类加载期间的分析(运行时)基本相同,但存在一些东西只能在编译期或者运行时检测

就比如说局部变量的final,JVM对于字节码的要求是越短越好,对于局部变量的final关键字会直接被消除,那如何保证其值不会变?那就轮到编译器来判断了

为什么不会去掉成员变量的final?因为JVM 运行时有可能用到(比如常量折叠、只读约束等)

解语法糖

语法糖是一些用来帮助程序员进行编程的特殊语法,或许其不严谨或不规范但是其能大幅度提升程序员的幸福度

包括泛型(是的,Java匪夷所思没有真正的实现泛型,详见类型擦除),自动拆装箱,自动变长参数等,这些语法会在这个阶段被替换成最基础的语法

字节码生成

这里是最后一个阶段:把语法树,符号表转化成字节码

字节码的格式极其严格,这里会把其严格的转化成字节码,并向其中添加一些其他的代码,比如类构造器,实例构造器

变量初始化,调用父类构造等等

并还会添加一些优化,比如把字符串的+替换成StringBuffer的append之类的

到此,编译结束


现在已经生成了一份详尽且严谨的字节码,接下来一步就是开始解释执行,并开始最大的舞台:后端编译及优化

http://www.dtcms.com/wzjs/500336.html

相关文章:

  • 做网站策划书吧网络营销的培训课程
  • b2c网站的促销策略玉溪seo
  • 网站优化吧百度手机网页版
  • 上线了做网站要钱seo深圳网络推广
  • 网站建设中的功能模块描述河南今日头条新闻
  • 做emu对网站有什么要求整站优化要多少钱
  • 响应设网站多少钱可以做惠州seo关键词
  • 建网站的专业公司正规的代运营公司
  • 佛山营销网站建设多少钱公司网站免费自建
  • 长宁区公司网站建设专业seo外包
  • 网站推广用什么方法最好百度网站名称
  • 优秀网站欣赏怎么查询百度收录情况
  • 移动端网站如何做开放式配电子商务主要干什么
  • 苹果企业网站建设天津关键词优化网排名
  • 网站设计及开发网站内容优化关键词布局
  • 仿站网站建设网络营销效果评估
  • 微交易网站建设网文网站排名
  • 陕西网站建设设计深圳网络推广公司有哪些
  • 怎么做自动下单网站seo精准培训课程
  • 北京大兴企业网站建设咨询如何注册自己的网站
  • 网站专题设计模板外链发布平台大全
  • 网站维护推广怎么做网站维护是做什么的
  • 贵州网站建设线上推广策划方案范文
  • 网站建设首选定制开发永久免费无代码开发平台网站
  • 宜昌模板网站建设网络推广的方法有
  • 网站要做手机版怎么做查网站域名
  • 建立个大型网站需要多少投入搜索引擎入口google
  • 网站开发页面怎么进公司业务推广
  • 内网穿透做网站seo百度快照优化公司
  • 上海建网站开发公司长沙企业网站设计