Java ,我们都很熟悉的编程语言 ,它从诞生至今已经度过了整整 25 个年头了 。
Java 最早起源于 1990 年 12 月 Sun 公司的内部项目 “Stealth 计划”,运用于嵌入式设备 ,是为了解决 C++ 在编写下一代智能家电(如微波炉)的程序设计时过高的复杂性以及常发的错误使用而诞生的 。 最初这门语言被命名为被命名为 “Oak” ,在1993 年因为 Oak 已被注册改名为 Java ,同时诞生还有一个小小的吉祥物 “Duke” 。
![e0a8be6bc2d74af4cf64d47fb1a2a981.png](https://i-blog.csdnimg.cn/blog_migrate/e40b32e6f6f5a7b42dec14ec62a99681.png)
Java 解决了什么问题 ?
我们都知道 ,人的习惯是很难改变的 。如果一件事物要替代人们已经熟悉并使用的另一件事物 ,就必须解决用户的痛点 。例如这些年高速发展的拼多多 ,靠的就是通过实实在在的 “低价” 直击下沉市场 ,从而蚕食掉原本一大块属于巨头的市场的 。
那么当年 Java 靠的是什么和 C ,C++ 厮杀 ,从而让人们转而使用 Java 语言来编写程序的呢 ?
我们都知道 Java 是一门面向对象的语言 ,最大的特征有两方面 :
一是 “书写一次,到处运行”(Write once ,run anywhere),拥有着极强的跨平台能力 ;
二是垃圾收集(GC, Garbage Collection),Java 通过垃圾收集器(Garbage Collector)回收分配内存,大部分情况下,程序员不需要自己操心内存的分配和回收 。
这些就是为了解决在当时 C++ 缺少垃圾回收系统,还有可移植的安全性、分布程序设计、和多线程功能存在的问题 。
今天我们就来谈谈 Java 是如何实现书写一次,到处运行的。
Java 是如何做到编写一次 ,到处运行的 ?
对于大部分语言来说 ,代码的生命周期要经过四个阶段 ,分别是 编码 ,编译 ,运行 ,调试 。
编码就是我们用我们熟悉的语言规范 ,写成我们容易理解的代码 ;编译是将我们所写的代码编译为机器可以执行的机器码 ;运行和调试就不用说了 ,字面意思 。
对于 C 语言来说 ,编译是直接将代码编译为机器可运行的机器码 ,这会带来极高的运行效率 ,但存在这样一个问题 ,C 语言的程序要经常需要调用操作系统层面 API 的情况下 ,为了支持多平台 ,需要为每一个不同 API 的平台都修改出一份专用的代码 。针对不同平台修改多次 ,这是一个非常大的痛点 。
而 Java 所宣传的 “Write once ,run anywhere” 直击痛点 。代码只需要编写一次 ,就能在各个平台上编译运行 ,这是多么诱人的特性 。
Java 实现这一特性依赖的就是 Java 虚拟机 ,也就是 JVM 。对于 Java 来说 ,一段代码的生命历程是这样的 :
编码 → Javac 编译字节码 → JVM 编译机器码 → 运行 → 调试
发现了吗 , Java 实现跨平台的核心在于将编译拆成了两步 ,先通过 Javac 编译成了 “.class” 类型的字节码 ,在通过 JVM 生成可运行的机器码 ,对 “编码” 和 “操作环境” 实现了解耦 ,通过中间层 JVM 来进行联系 。对底层 API 的调用在代码中都是一致的 ,而在编译时根据 JVM 平台的不同而不同 。
当然 JVM 做的可不止这些 ,JVM 有多达上千个可选项 ,还有例如基于于 JIT 实现热点代码是解释执行 ,AOT ,C1 C2 模式的区别 等有意思的特性我们以后再来讨论 。
欢迎来我的博客玩 ,我的博客还蛮大的 ,嘿嘿