1,java跨平台原理
java之所以具有跨平台性,是因为它对外提供了统一的java Api;对内实现了针对不同操作系统的jvm虚拟机;它首先将java文件编译成字节码文件,再编译成机器码,再由jvm虚拟机进行调用native方法进行执行。
2,执行顺序
3,编译器
编译器分为前端编译器、JIT编译器、AOT编译器。
A,前端编译器
因为从java文件编译为class文件这一过程发生在整个程序执行的前期,所以称之为前端编译器。前端编译器, 主要种类有:Sun的Javac、Eclipse JDT的增量式编译器(ECJ)。
B,JIT编译器( Just In Time Compiler)
即时编译器,将前端编译器编译过后的字节码文件,再编译成本地机器码。
C,AOT编译器(AHEAND OF TIME)
静态提前编译,即在程序运行期间,直接将java文件编译成本地机器码,编译时间比JIT来的快,但编译成的本地机器码没有JIT质量高。
4,前端编译过程
语法与此法分析:
a.语法分析:将源代码字符流转换为标记(Token:编译过程最小元素)集合。
b.词法分析:根据标记序列构造抽象语法树(AST:用来描述程序代码语法结构的树形表示方式,每一个节点代表程序中的一个语法结构。
符号表填充
符号表是由一组符号地址和符号信息构成的表格。符号表中所登记的信息在编译的不同阶段都要用到,在语义分析(后面的步骤)中,符号表所登记的内容将用于语义检查和产生中间代码,在目标代码生成阶段,党对符号名进行地址分配时,符号表是地址分配的依据。
注解处理
插入式注解处理器,编译期间处理注解,读取,修改,删除语法树中的任意元素,编译器会根据修改与否,重新回到解析及符号表填充阶段进行处理。
语义分析,字节码生成
a.标注检查,例如变量使用前是否声明,变量与赋值的数据之间类型是否匹配等。
b.数据集控制流是否分析,局部变量是否赋值,方法返回值验证,受检异常的处理等。
c.语法糖解析,for循环,泛型,拆装箱等。
d.字节码生成,转化成字节写入磁盘。
5,JIT编译过程
6,类加载
加载:将class文件加载进行jvm,通过类的权限定名来获取其定义的二进制流,将二进制流转化为静态变量及class类对象存放在方法区(元数据)
验证:对class文件进行验证,是否符合jvm规范以及是否安全
准备:对类中变量进行内存分配,并设置初始值
解析:将常量池的符号引用替换为直接引用,直接引用的目标必定存在于内存中。
初始化:执行类构造器方法, 主要对静态变量进行赋值操作;若该类的父类没有被初始化,则先初始化其父类。
7,类加载器
BootStrap ClassLoader: 引导类加载器,由C++实现,是jvm的一部分。负责加载JAVA_HOME/LIB下的类,或通过-Xbootclasspath参数指定路径中的,且被 虚拟机认可(按文件名识别,如rt.jar)的类。
Extension ClassLoader: 扩展类加载器,负责加载JAVA_HOME/LIB/ext下的或java.ext.dirs系统变量路径下的类。
Application ClassLoader: 应用加载器,负责加载我们日常开发的java类,也就是classpath下的类。
USER ClassLoader: 自定义加载器,可自行定义实现的类加载器。
8,双亲委派模式
当一个类加载器收到类加载请求,它首先会查询是否已经加载过,如果是则返回;如果不是则向上级加载器请求,上级加载依旧先查询是否已被自己加载过,如果不是,则继续向上级请求;直到最上级的时候,会查看是否是本加载器加载,如果不是则往下传递,交由下级加载器;下级加载器同样判断是否是本加载器所要加载的类,如果是则加载,不是继续往下传递。
好处: 避免类的重复加载,避免java核心api被篡改。
什么时候违背了双亲 委派模式?
当java核心类需要调用应用类的时候,父级加载器无法加载该类,只能由子类应用加载器加载,这时候会通过线程上下文加载器加载。这就违背了双模。