一、Java语言规范:
1.java语法
java的语法比较简单,对于分支语句的结构如下:
if then Statement:
if(Expression) Statement
对应的代码如下:
if(true){do sth;}
ArgumentList:
在定义一个方法时可能需要指定方法的参数,这个参数个数可以是固定的,也可以是不固定的。jdk1.7之后支持多个参数
2.词法结构:
在源代码中需要满足如下的词法结构:
行终结符:CR(回车) or LF(换行,Linux操作系统下表示下一行) or CR LF(回车换行,在windows操作系统下表示下一行)
空白符:空格 tab \t 换页 \f 行终结符
注释:多行注释,单行注释
标示符:Java字符是Unicode编码,任何的Unicode编码都可以是标示符。下面是一个中文做函数名的例子:
public static void 输出消息() {
System.out.println("中文方法哦");
}
public static void main(String[] args) {
输出消息();
}
数字:
Int- 0xDada_Cafe, jdk 1.7之后运行使用下划线分隔数字,好处是对于特别大的数字可以比较清晰的看到
Long-Long型数字都是以L结尾的 0777L 2_147_483_648L 0xC0B0L
Fload-单精度浮点,以f结尾来表达 2.17f 3.022137e+23f
Double-双精度浮点,直接用数字来表示 2.17 3e124
操作-+= -= *= /= &= |= ^= %= <<= >>= >>>=
在词法中定义哪些是合法的,哪些是不合法的
4.类型
元类型:byte short int long fload char
元类型不是对象,在java语言中对元类型变量的修改不会影响其他的变量,但是对对象的修改会影响所有引用这个对象的变量。
对象:String Map等是对象类型
3.变量
java语言中定义变量需要指定该变量的具体数据类型,是元类型还是对象,同时为了避免空指针的问题还需要在定义变量的时候赋值一个初始值。
比如:
int index=0;
二、JVM规范
java语言和JVM相对独立,只要符合JVM规范都可以在JVM上运行,比如Groovy、Scala、Clojure等。
1.JVM中数的表达:
jvm中用补码来表示整数,这样做有两点好处:1.可以无歧义的表示数字0,2.可以方便的进行加法运算(减法运算可以看做是加法的一种)
原码:第一位为符号位(0为整数,1位负数)
反码:符号位不动,原码去反
负数补码:符号位不动,反码加1
整数补码:和原码相同
根据以上规则数字5的原码和补码都是00000101(用一个字节来表示一个数字),-6的原码、反码和补码如下:
-6
原码:10000110
反码:11111001
补码:11111010
-1
原码:10000001
反码:11111110
补码:11111111
所以在计算机中用11111111表示-1,用11111010表示-6
-1+2=1用补码可以如下表示:
11111111
+ 00000010
= 00000001
由于符号位也参与预算,可以看出用补码的方式可以很方便的进行加法运算。
float的表示与定义
jvm中用32位表示单精度数字,格式如下:s eeeeeeee mmmmmmmmmmmmmmmmmmmmmm
第1位表示符号,接下来的8位表示指数,所以指数的大小范围是从-127到128,剩下的23尾表示尾数也就是科学计数法的小数部分,实际上尾数是有24尾,因为规定e全为0,尾数附加位为0,否则附加位为1
这种方式表示的数字的计算公式是:sm2^(e-127)
下面看一下-5的表示:
1100000010100000000000000000000
-12(129-127)*(20+2-2)=-1*22(1+0.25)=-5
2.一些特殊方法:
:类构造方法,能够对静态变量和静态代码块进行初始化。
:实例构造器,它能够对非静态变量进行初始化,也就是new一个对象的时候,jvm会默认给该实例增加一个构造函数来初始化静态变量。
3.jvm指令集:
类型转化:l2i:长整型转化为整型
出栈入栈操作:aload astore,jvm没有寄存器来存储值,所有的值都是通过出栈入栈来操作的。
运算:iadd isub,如果遇到运算符,就从堆栈中弹出两个数进行操作
流程控制:ifeq ifne,比较相等,不相等,跳转等
函数调用:invokevirtual invokeinterface invokespecial invokestatic 调用虚函数,函数等
4.jvm需要对Java Library提供支持:
反射 java.lang.reflect
ClassLoader 最重要的启动类加载器是在jvm中实现的
初始化class和interface
安全相关
多线程
弱引用
这些功能没法通过Java语言本身来实现,所以需要jvm提供。
5.jvm的编译:
源码到jvm指令的对应格式
jvm反汇编的格式:
[ [ … ]] []
index是索引,标识该反汇编的语句的序号,可以用于流程控制
opcode是操作码,比如入栈出栈操作
operand是操作数,可以是一个或者多个
comment是注释
查看反汇编代码的方法是使用命令javap -c Demo.class