Java的理解
谈谈你对Java的理解 面试问题
平台无关性
GC
语言特性
面对对象
类库
异常处理
Compile Once,Run Anywhere(如何实现平台无关的?)
编译时:javac
运行时:java
.java文件首先经过javac编译生成字节码。将字节码保存在.class文件中。.class文件是跨平台的基础。在由不同平台的JVM进行解析,java语言在不同的平台上运行时不需要进行重新编译,java虚拟机在执行字节码的时候,把字节码转换成具体平台上的机器指令
package com.binglian.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);
}
}
用指令编译
首先javac ByteCodeSample.java
然后运行 java ByteCodeSample
使用javap进行反编译查看class文件
先看一下javap -help 指令文档
javap -c ByteCodeSample
JVM字节码 都已经注释好了
警告: 二进制文件ByteCodeSample包含com.binglian.bytecode.ByteCodeSample
Compiled from "ByteCodeSample.java"
public class com.binglian.bytecode.ByteCodeSample {
public com.binglian.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放入栈顶 这些都离不开栈
1: istore_1 //把栈顶的值放入局部变量
2: iconst_5 //把常量5放入栈顶
3: istore_2 //把栈顶的值放入局部变量
4: iinc 1, 1 //将变量1加上1 也就是1+1
7: iinc 2, 1 //将变量2加上1 也就是5+1
10: getstatic #2 //获取PrintStream静态域 压入栈顶 // Field java/lang/System.out:Ljava/
io/PrintStream;
13: iload_1 //变量1推送至栈顶
14: invokevirtual #3 //打印它的值 // Method java/io/PrintStream.printl
n:(I)V
17: getstatic #2 //获取PrintStream静态域 压入栈顶 // Field java/lang/System.out:Ljava/
io/PrintStream;
20: iload_2 //变量2的值推送到栈顶
21: invokevirtual #3 //打印它的值 // Method java/io/PrintStream.printl
n:(I)V
24: return
}
为什么jvm不直接将字节码解析成机器码才去执行
1.每次执行都需要各种检查(语法,句法,语义的检查,每次执行的时候,这些语义分析结果不会被保存下来,因此引入字节码,每次执行程序是不需要各种校验和补全的)
2.兼容性,可以将别的语言(groovy,scala)解析成字节码