首先要搞清楚两个问题,java 是怎样从编码到执行的真个过程,到底什么是jvm?
我们有一个文件x.java->执行javac->变成x.class ,当我们调用java命令的时候class会被装载到内存叫classLoader。一般的情况下我们写自己类文件的时候会用到java的类库,所以它要把java类库相关的类也装载到内存里面,装载完成之后会调用字节码解释器或者即时编译器来进行解释或编译,编译完之后有执行引擎开始执行,执行引擎下面面对的就是操作系统的硬件了,这一部分的内容就叫jvm。
这里面还有一个问题,java其实是解释执行和编译执行可以混合的。
jvm与java无关
java虚拟机怎么才能做到这么多语言都网上跑呢,关键的原因就是class这个东西,任何的语言只要是能编译成class,符合class文件的规范你就可以扔到java虚拟机上去执行。
目前常用的最多的java虚拟机就是HotPot。在命令行里输入 :java -version,就会输出虚拟机的名字,执行模式,版本等信息
JDK、JRE、JVM
在这里需要解释一些相应的概念,JDK-JRE-JVM到底是一个什么样的关系,下面这一张图一看应该就能明白,jvm叫java的虚拟机只是来执行的;jre运行时环境,java要想在操作系统上运行,除了虚拟机之外java的核心类库得有;jdk是Java开发工具包,包含了jre和jvm、
Class File Format
刚刚看到的这个得java虚拟机是以class文件为核心,这个class文件是什么呢?
整个class文件的格式是一个二进制字节流,这个二进制字节流是有java虚拟机来解释的。
使用sublime用16进制打开class文件之后可以看出每一部分有多长,一般u1,u2,u3....u8,u指的是无符号整数,u1就是一个字节。前几位一般都一样,前面的四个字节指的是这个文件的同意标识符,当我们看到CA FE BA BE 的时候,就知道他是java编译完的class文件。这四个字节叫做magic Number,魔术。
我们可以使用多种方式看到ByteCode
1.javap - java自带的觉javap的命令
2.JBE- 他除了可以观察二进制码之外还可以直接修改
3.JClassLib + IDEA插件之一,这个是我最常用的
这个插件用起来很简单,安装完之后就会有选项->show Bytecode With jclasslib
我们来回顾一下,这个class文件有好多种类型,它是一环套一环的,这个class文件有那么几个:
1.Magic Number
2.Minor Version (小号)/Major Version(主号)
3.constant_pool_count(有多少个常量池)
4.常量池-1具体的内容有很多种类型
5.access_flags (指的是整个class你前面写的是public还是private等)
6.this_class (我当前的这个类是谁)
7.super_class(父类是谁)
8.Interface_count(实现了哪些接口)
9.Interface(接口的索引)
10.fields(有哪些属性)
access_flags:是不是public的,是不是static的,是不是final的???
name_index:名称的索引
descriptor_index:描述符,到底是什么类型的
attributes:另外它所附加的一些属性
11.methods(方法的各种结构,到底是怎么样进行标识的,它的名字的索引,描述符的索引,附加属性)