代码编译的结果从本地机器码转变为字节码,是存储格式发展的一小步,却是编程语法发展的一大步——深入理解java虚拟机
什么是编译?将源程序翻译成计算机语言,就是二进制代码,在java中是将.java文件也就是源程序翻译成.class的字节码文件
Java源码编译由三个过程组成:
1、源码编译机制
2、类加载机制
3、类运行机制
主要介绍源码编译和类加载
一、源码编译:由编译器完成,主要是将java文件编译成字节码文件(class文件)。字节码文件格式主要分为两部分:常量池和方法字节码
二、类加载
类的生命周期是从被加载到JVM开始,到卸载出内存结束。有七个阶段。其中到初始化之前的都是属于类加载的部分。
加载-----验证-----准备----解析-----初始化----使用----卸载
用final修饰某个类变量(相当于常量)时,它的值在编译时就已经确定好放入常量池了,所以在访问该类变量时,等于直接从常量池中获取,并没有初始化该类。
类加载器:是负责将可能是网络上、也可能是磁盘上的class文件加载到内存中。并为其生成对应的java.lang.class对象。
怎样才算一个同一个类?在java中一个类用全限定类名(包名+类名)为唯一标识,但是在JVM中,一个类用其全限定类名+类加载器作为唯一标识。也就是说,在java中的同一个类,如果用不同的类加载器加载,则生成的class对象认为是不同的。
当JVM启动时,会形成由三个类加载器组成的初始化类加载器层次结构。
1、启动类加载器:BootstrapClassLoader
2、扩展类加载器:Extension ClassLoader
3、系统类加载器:App ClassLoader
三、编译时和运行时
java变量类型有两个类型:编译时类型和运行时类型
编译时类型由声明该变量时使用的类型决定,运行时类型由实际覆盖该变量的对象绝对。举个例子,声明Dog、Cat、Animal三个类。Dog和Cat继承Animal。Animal a=new dog(),编译时类型是Animal。运行时类型是Dog。
学设计模式的时候提到过,少用继承,多用组合。从某中角度讲是因为继承发生在编译时,因为它是静态的。组合发生在运行时,因为具有动态性和灵活性。
反射就是可以将一个程序(类)在运行时获得该程序(类)的信息的机制,也就是获得在编译期不可能获得的类的信息,因为这些信息是保存在Class对象中的,而这个Class对象是在程序运行时动态加载的。