• Java印象
  • 编译 or 解释


看了杨晓峰在极客时间里的《谈谈你对Java平台的理解?》(这是一个付费类栏目),我也接机总结一下对Java的印象。文中提到了两个问题:1. 谈谈你对 Java 平台的理解?2. “Java 是解释执行”,这句话正确吗?

文中给出的典型回答(版权考虑,只是部分内容):
Java 本身是一种面向对象的语言,最显著的特性有两个方面,一是所谓的“一次编译,到处执行”(Compile once, run anywhere),能够非常容易地获得跨平台能力;另外就是垃圾收集(GC, Garbage Collection),Java 通过垃圾收集器(Garbage Collector)回收分配内存,大部分情况下,程序员不需要自己操心内存的分配和回收。

我们日常会接触到 JRE(Java Runtime Environment)或者 JDK(Java Development Kit)。 JRE,也就是 Java 运行环境,包含了 JVM 和 Java 类库,以及一些模块等。而 JDK 可以看作是 JRE 的一个超集,提供了更多工具,比如编译器、各种诊断工具等。

对于“Java 是解释执行”这句话,这个说法不太准确。我们开发的 Java 的源代码,首先通过 Javac 编译成为字节码(bytecode),然后,在运行时,通过 Java 虚拟机(JVM)内嵌的解释器将字节码转换成为最终的机器码。但是常见的 JVM,比如我们大多数情况使用的 Oracle JDK 提供的 Hotspot JVM,都提供了 JIT(Just-In-Time)编译器,也就是通常所说的动态编译器,JIT 能够在运行时将热点代码编译成机器码,这种情况下部分热点代码就属于编译执行,而不是解释执行了。

Java印象

这里是我对Java的总体印象,Java已经不只是一种编程语言,是一个由一系列软件、规范和框架组成的一个平台或生态体系。

java项目评论模块实现 java the complete reference评价_Java

Java有诸多的特点,比如“一次编写,到处运行”,这是当年Sun为Java的跨平台性宣传的口号。Java语言是在一个为智能家电的项目中被发明出来的,项目本来打算用C++语言开发,却被C++复杂的平台API搞得焦头烂额,于是就有了这个项目的副产品Java(那时的名字还不叫Java)。

编译 or 解释

编译与解释,区别在于代码是在什么时候被翻译成目标CPU的指令。对C/C++语言或者其他编译型语言来说,编译生成了目标文件,比如windows exe文件。这个目标文件是针对特定的 CPU 体系的,为 ARM 生成的目标文件,不能被用于 MIPS 的 CPU。这段代码在编译过程中就已经被翻译成了目标 CPU 指令,所以,如果这个程序需要在另外一种 CPU 上面运行,这个代码就必须重新编译。
对于解释型语言,比如python来说,这种代码一般不是针对特定的 CPU 平台,他们是在运行过程中才被翻译成目标 CPU 指令的,因而,在 ARM CPU 上能执行,换到 MIPS 也能执行,换到 X86 也能执行,不需要重新对源代码进行编译。

Java不同于一般的编译语言或解释型语言。它首先将源代码编译成字节码,然后依赖各种不同平台上的虚拟机来解释执行字节码,从而实现了“一次编写,到处运行”的跨平台特性。在早期JVM中,这在一定程度上降低了Java程序的运行效率。但在J2SE1.4.2发布后,Java的运行速度有了大幅提升。

编译
将Java源文件(.java)翻译成Java字节码文件(.class )。

javac Welcome.java //将Java源代码翻译成Java字节码,并且生成.class文件 
java Welcome //运行字节码

JVM java虚拟机
解释Java字节符的程序。不是物理机器,也不是虚拟机(VMWare)。
Java字节码可以在不同的硬件平台和操作系统上运行,只要安装了JVM(JRE的一部分)。

类加载器(class loader)
将类的字节码加载到内存中的程序。
在执行一个Java程序时,JVM首先会用一个称为类加载器的程序将类的字节码加载到内存中。如果程序中使用了其他类,类加载程序会在需要它们之前动态地加载他们。当加载该类后,JVM使用一个成为字节码验证器(bytecode verifier)的程序来检验字节码的合法性,确保字节码不会违反Java的安全规范。