1.6 JVM语言生态

下面是一个来自Java官网文档(http://docs.oracle.com/javase/8/docs/)里的一张Java技术模块架构图,如图1-3所示。

为了在JVM上正确运行我们的程序,只需要按照规范生成正确的class文件,然后加载到JVM中执行文件中指定的操作字节指令码(byte code)即可。

在过去20多年的发展历程中(1991—2017年,如果算上最初的称为Oak语言的Java前生),Java语言、JVM、API库和框架、应用工具和Web服务器的速度、稳定性和功能方面在不断发展,已被公认为是开发企业级服务的首选技术栈。

图1-3 Java技术模块架构图

JVM最初是为了支持Java编程语言。然而随着时间的推移,越来越多的语言被改编、设计并运行在JVM上。除了Java语言外,比较知名的JVM上的编程语言还有Groovy、Scala和Clojure等。

JVM上主流编程语言历史时间轴概览如图1-4所示。

图1-4 JVM上主流编程语言历史时间轴概览

说明:计算机中的所有问题,都可以通过向上抽象封装一层来解决。

Java虚拟机对各个平台而言,实质上是各个平台上的一个可执行程序。例如在Windows平台下,Java虚拟机对于Windows而言,就是一个java.exe进程而已。

通常情况下,在JVM平台上从源代码编译到JVM上执行的整体过程如图1-5所示。

图1-5 在JVM平台上从源代码编译到JVM上执行的整体过程

其中,运行在JVM上的字节码文件是不依赖于硬件和操作系统的二进制格式的文件。依赖硬件和操作系统的部分,由JVM分别在这些平台上来实现。例如,JDK 8的各个平台的软件版本如图1-6所示。

图1-6 JDK 8的各个平台的软件版本

我们经常说的Java语言是平台无关的,即跨平台的,其实针对从Java、Scala、Kotlin、Groovy等的源代码到JVM字节码这一层是平台无关的。

但是,真正把JVM字节码通过解释器映射到不同平台(操作系统,CPU硬件架构)上时,JVM就必须针对各个平台实现一套解释器。只是这一层通过抽象封装,对Java、Scala、Kotlin、Groovy程序员而言已经完全透明,无须再做相关的工作而已。

在下一代普遍可接受语言(next mass-appeal language)中,人的因素应该是至关重要的。在功能方面,应该具备如下特性:

  •  类C的语法(容易被大众程序员所接受,很好用也很熟悉);
  •  静态类型(动态类型过于松散并且性能有限,不适用于大型项目);
  •  遵循面向对象程序设计OOP思想,同时支持函数式编程(FP);
  •  反射(从而避免静态类型限制);
  •  属性(getter和setter实在是太让人讨厌了);
  •  高阶函数,Lambda与闭包;
  •  Null判断(提供一个判断变量能否为null的方式);
  •  并发协程;
  •  模块化;
  •  完善的工具支持;
  •  可扩展性(语言的设计具备很好的可扩展性);
  •  ...

程序语言设计其实堪比艺术品设计,每个开发者的喜好与审美都不同,有自己的风格与特征,所以设计出一门好的编程语言确实不容易。

生命只有一次,所以不要去做一些重复无聊的事情。能交给计算机做的,就尽量交给计算机去做。未来,人工智能将取代大部分的重复手工劳动,将大大解放人类的劳动力,从而使得人类能够花更多的时间和精力去创造,去创新。而人工智能的本质,就是对人类智能的抽象建模。人类设计的操作系统、浏览器、办公软件、画图设计工具、3D建模软件、电商系统、金融平台、社交APP,不就是另一种层次上的人工智能吗?这些东西,背后都是01的映射。当然,01背后是物理层次量子微观的世界了,更加奥妙无穷。

纵览整个计算机的发展史,最重要的思想非“抽象”莫属。一层层的抽象封装了实现的细节,经过计算机技术的不断发展,到了今天的互联网(云计算,大数据,机器智能)时代。

同时,程序员写代码从最初的拿着符号表在纸带上打孔,到使用近似自然语言的高级编程语言来编程(当然背后少不了编译器、解释器,还有的是先通过虚拟机中间字节码这一层,再通过解释器映射到机器码,最后在硬件上进行高、低电平的超高频率的“舞蹈”),以及当今各种库API、框架、集成开发工具集、智能化的编码提示、代码生成等技术,使得现在的程序员,能够更多地去关注问题本身及逻辑的实现。

从只有少数技术人员会用的命令行的UNIX、DOS操作系统,到人性化的GUI(图形用户界面)操作系统,再到移动互联网时代的智能设备,计算机与互联网越来越多地融入到了人们生活的方方面面。

正如解决数学问题时通常我们会谈“思想”,如反证法、化繁为简等,解决计算机问题也有很多非常出色的“思想”。之所以称为思想,是因为“思想”有拓展性与引导性,可以解决一系列问题。

解决问题的复杂程度直接取决于抽象的种类及质量。将结构、性质不同的底层实现进行封装,向上提供统一的API接口,让使用者觉得就是在使用一个统一的资源,或者让使用者觉得自己是在使用一个底层不直接提供而“虚拟”出来的资源。