Java的理解

谈谈你对Java的理解 面试问题

平台无关性

GC

语言特性

面对对象

类库

异常处理

 

 

 

Compile Once,Run Anywhere(如何实现平台无关的?)

编译时:javac

运行时:java

.java文件首先经过javac编译生成字节码。将字节码保存在.class文件中。.class文件是跨平台的基础。在由不同平台的JVM进行解析,java语言在不同的平台上运行时不需要进行重新编译,java虚拟机在执行字节码的时候,把字节码转换成具体平台上的机器指令

 

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

Java的理解

 

使用javap进行反编译查看class文件

先看一下javap -help 指令文档

Java的理解

 

javap -c ByteCodeSample

Java的理解

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)解析成字节码