二、Java怎樣實現一次編譯到處運行(平台無關性)
1.java平台無關性原理
Java源碼首先被編譯成字節碼,再由不同平台的JVM進行解析,JAVA語言在不同的平台上運行時不需要進行重新編譯,Java虛擬機在執行字節碼的時候,把字節碼轉換成具體平台上的機器指令。
2.為什么JVM不直接將源碼進行編譯成機器碼去執行
(1)准備工作太過繁瑣
JVM每次進行編譯的時候都會對源代碼進行各種檢查,糾錯
(2)兼容性
JVM不僅僅可以給java語言編譯成的class文件進行解釋,還可以對任何語言,只要是解釋為.class字節碼都可以解釋
3.查看(.class)字節碼
(1)准備一個簡單的java文件
package com.interview.javabasic.bytecode; public class ByteCodeSample { public static void main(String[] args) { int i=1,j=5; i++; ++j; System.out.println(i); System.out.println(j); } }
(2)javac進行編譯成.class文件
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package com.interview.javabasic.bytecode; public class ByteCodeSample { public ByteCodeSample() { } public static void main(String[] var0) { byte var1 = 1; byte var2 = 5; int var3 = var1 + 1; int var4 = var2 + 1; System.out.println(var3); System.out.println(var4); } }
(3)通過javap指令查看.class文件反編譯代碼
Compiled from "ByteCodeSample.java" public class com.interview.javabasic.bytecode.ByteCodeSample { public com.interview.javabasic.bytecode.ByteCodeSample(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: iconst_1 1: istore_1 2: iconst_5 3: istore_2 4: iinc 1, 1 7: iinc 2, 1 10: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 13: iload_1 14: invokevirtual #3 // Method java/io/PrintStream.println:(I)V 17: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 20: iload_2 21: invokevirtual #3 // Method java/io/PrintStream.println:(I)V 24: return }