- 当java源代码成功编译成字节码后,如果想在不同的平台上面运行,则无须再次编译
- 这个优势不再那么吸引人了。 Python、PHP、Per1、Ruby、Lisp等有强大的解释器。
- 跨平台似乎己经快成为一门语言必选的特性。
Java虚拟机不和包括]ava在内的任何语言绑定,它只与“Class文件”这种特定的二进制文件格式所关联。无论使用何种语言进行软件开发,只要能将源文件编译为正确的Class文件,那么这种语言就可以在Java虚拟机上执行。可以说,统一而强大的Class文件结构,就是Java虚拟机的基石、桥梁。
所有的JVM全部遵守Java虚拟机规范,也就是说所有的JVM环境都是一样的,这样一来字节码文件可以在各种JVM上运行
- 前端编译器的主要任务就是负责将符合Java语法规范的Java代码转换为符合JVM规范的字节码文件。
- javac是一种能够将Java源码编译为字节码的前端编译器。
- javac编译器在将]ava源码编译为一个有效的字节码文件过程中经历了4个步骤,分别是词法解析、语法解析、语义解析以及生成字节码
Oracle的JDK软件包括两部分内容:
- 一部分是将Java源代码编译成Java虚拟机的指令集的编译器
- 另一部分是用于实现]ava虚拟机的运行时环境。
前端编译器vs后端编译器
Java源代码的编译结果是字节码,那么肯定需要有一种编译器能够将Java源码编译为字节码,承担这个重要责任的就是配置在path环境变量中的 javac编译器。 javac是一种能够将Java源码编译为字节码的前端编译器。
1.3 透过字节码指令看代码细节 1.3.1 例一:public class IntegerTest {
public static void main(String[] args) {
Integer x = 5;
int y = 5;
System.out.println(x == y); // true
Integer i1 = 10;
Integer i2 = 10;
System.out.println(i1 == i2);//true
Integer i3 = 128;
Integer i4 = 128;
System.out.println(i3 == i4);//false
}
}
字节码:通过观察源码可以看出-128-127不会new出新对象
0 iconst_5 1 invokestatic #21.3.2 例二:4 astore_1 5 iconst_5 6 istore_2 7 getstatic #3 10 aload_1 11 invokevirtual #4 14 iload_2 15 if_icmpne 22 (+7) 18 iconst_1 19 goto 23 (+4) 22 iconst_0 23 invokevirtual #5 26 bipush 10 28 invokestatic #2 31 astore_3 32 bipush 10 34 invokestatic #2 37 astore 4 39 getstatic #3 42 aload_3 43 aload 4 45 if_acmpne 52 (+7) 48 iconst_1 49 goto 53 (+4) 52 iconst_0 53 invokevirtual #5 56 sipush 128 59 invokestatic #2 62 astore 5 64 sipush 128 67 invokestatic #2 70 astore 6 72 getstatic #3 75 aload 5 77 aload 6 79 if_acmpne 86 (+7) 82 iconst_1 83 goto 87 (+4) 86 iconst_0 87 invokevirtual #5 90 return
public class StringTest {
public static void main(String[] args) {
String str = new String("hello") + new String("world");
String str1 = "helloworld";
System.out.println(str == str1); // false
String str2 = new String("helloworld");
System.out.println(str == str2); // false
}
public void method1(){
}
public void method1(int num){
}
}
0 new #21.3.3 例三:3 dup 4 invokespecial #3 > 7 new #4 10 dup 11 ldc #5 13 invokespecial #6 > 16 invokevirtual #7 19 new #4 22 dup 23 ldc #8 25 invokespecial #6 > 28 invokevirtual #7 31 invokevirtual #9 34 astore_1 35 ldc #10 37 astore_2 38 getstatic #11 41 aload_1 42 aload_2 43 if_acmpne 50 (+7) 46 iconst_1 47 goto 51 (+4) 50 iconst_0 51 invokevirtual #12 54 new #4 57 dup 58 ldc #10 60 invokespecial #6 > 63 astore_3 64 getstatic #11 67 aload_1 68 aload_3 69 if_acmpne 76 (+7) 72 iconst_1 73 goto 77 (+4) 76 iconst_0 77 invokevirtual #12 80 return
class Father {
int x = 10;
public Father() {
this.print();
x = 20;
}
public void print() {
System.out.println("Father.x = " + x);
}
}
class Son extends Father {
int x = 30;
// float x = 30.1F;
public Son() {
this.print();
x = 40;
}
public void print() {
System.out.println("Son.x = " + x);
} //Son.x = 0 Son.x = 30
}
public class SonTest {
public static void main(String[] args) {
Father f = new Son();
System.out.println(f.x); // 20
}
}
结果:
输出结果 Son.x = 0 Son.x = 30 20
0 aload_0 1 invokespecial #12. 虚拟机的基石:class文件 3.Class文件结构 4. 使用javap指令解析Class文件> 4 aload_0 5 bipush 30 7 putfield #2 10 aload_0 11 invokevirtual #3 14 aload_0 15 bipush 40 17 putfield #2 20 return 0 getstatic #4 3 new #5 6 dup 7 invokespecial #6 > 10 ldc #7 12 invokevirtual #8 15 aload_0 16 getfield #2 19 invokevirtual #9 22 invokevirtual #10 25 invokevirtual #11 28 return



