1. Java 语言概述与开发环境

空~2022年6月6日
  • java
大约 14 分钟

1. Java 语言概述与开发环境

Java 语言发展简史

1990 年 Sun 公司成立了一个由 James Gosling 领导的“Green 计划”,准备为智能家电设计一套通用控制系统。Green 团队最初打算采用 C++语言进行编写,但发现 C++存在许多问题,于是便创造了一个种全新的语言: Oak(橡树)。

1992 年,Green 计划被转化成了“FirstPerson 有限公司”,一个 Sun 公司的全资子公司。FirstPerson 团队对建造一种高度交互的设备感兴趣,当时代华纳公司发布了一个关于电视机顶盒的征求提议书时(Request for proposal),FirstPerson 改变了他们的目标,作为对征求意见书的响应,提出了一个机顶盒平台的提议。但是有线电视业界觉得 FirstPerson 的平台给予用户过多的控制权,因此 FirstPerson 的投标败给了 SGI。与 3DO 公司的另外一笔关于机顶盒的交易也没有成功,由于他们的平台不能在电视工业产生任何效益,公司被并回 Sun 公司。

1994 年,互联网和浏览器的出现给 Oak 语言带来了生机,Gosling 对 Oak 进行了小规模调整,并用该语言写了一个小型的网页浏览器:WebRunner(后改名为 HotJava)。Sun 公司高层看了浏览器的效果并给予了高度的评价。当时 Oak 这个商标已经被别人注册,于是便将 Oak 改名为 Java。

1995 年 Sun 公司开源了 Java 语言,几个月后,Java 大火,有 10 多万人访问 Sun 公司的网页。

2009 年 Oracle 宣布将以每股 9.5 美元的价格收购 Sun,该交易的总价值约为 74 亿美元。 而 Oracle 通过收购 Sun 公司获得了两项软件资产 : Java 和 Solaris 。

Java 程序运行机制

Java 语言是一种特殊的高级语言,它既有解释型语言的特征,又有编译型语言的特征。Java 程序要先经过编译,后解释两个步骤。

高级语言的运行机制

计算机语言按程序的执行方式可以分为编译型和解释型。

编译型

编译型语言是指使用专门的编译器,针对特定平台(操作系统)将某种高级语言源代码一次性"翻译"成可被该平台硬件执行的机器码(包括机器指令和操作数),并包装成该平台所能识别的可执行性程序的格式,这个转换过程称为编译 (Compile) 。 编译生成的可执行性程序可以脱离开发环境,在特定的平台上独立运行。

因为编译型语言是一次性地编译成机器码,所以可以脱离开发环境独立运行,而且通常运行效率较高 ; 但因为编译型语言的程序被编译成特定平台上的机器码,因此编译生成的可执行性程序通常无法移植到其他平台上运行; 如果需要移植,则必须将源代码复制到特定平台上,针对特定平台进行修改,至少也需要采用特定平台上的编译器重新编译。

现有的 C 、 C++、 Objective-C 、 Swift、 Kotlin 等高级语言都属于编译型语言。

解释型

解释型语言是指使用专门的解释器对源程序逐行解释成特定平台的机器码并立即执行的语言。解释型语言通常不会进行整体性的编译和链接处理,解释型语言相当于把编译型语言中的编译和解释过程混合到一起同时完成。可以认为: 每次执行解释型语言的程序都需要进行一次编译。

因此解释型语言的程序运行效率通常较低,而且不能脱离解释器独立运行。但解释型语言有一个优势 : 跨平台比较容易,只需提供特定平台的解释器即可,每个特定平台上的解释器负责将源程序解释成特定平台的机器指令即可。 解释型语言可以方便地实现源程序级的移植,但这是以牺牲程序执行效率为代价的 。

现有的 JavaScript、 Ruby 、 Python 等语言都属于解释型语言。

提示

编译型语言通常运行效率较高,但无法跨平台

解释型语言跨平台容易,但程序执行效率通常不如编译型语言

Java 程序的运行机制和 JVM

Java 语言比较特殊,由 Java 语言编写的程序需要经过编译步骤,但这个编译步骤并不会生成特定平台的机器码,而是生成一种与平台无关的字节码(也就是*.class 文件) 。

当然,这种字节码不是可执行的,必须使用 Java 解释器来解释执行。 因此可以认为: Java 语言既是编译型语言,也是解释型语言。 或者说, Java 语言既不是纯粹的编译型语言,也不是纯粹的解释型语言 。 Java 程序的执行过程必须经过先编译、后解释两个步骤,如图所示 。

java程序运行机制

Java 语言里负责解释执行字节码文件的是 Java 虚拟机,即 JVM (Java Virtual Machine) JVM 是可运行 Java 字节码文件的虚拟计算机。所有平台上的 JVM 向编译器提供相同的编程接口 , 而编译器只需要面向虚拟机,生成虚拟机能理解的代码, 然后由虚拟机来解释执行。

在一些虚拟机的实现中,还会将虚拟机代码转换成特定系统的机器码执行,从而提高执行效率。

当使用 Java 编译器编译 Java 程序时,生成的是与平台无关的字节码,这些字节码不面向任何具体平台,只面向 JVM。

不同平台上的 JVM 都是不同的,但它们都提供了相同的接口 。 JVM 是 Java 程序跨平台的关键部分,只要为不同平台实现了相应的虚拟机,编译后的 Java 字节码就可以在该平台上运行。

显然,相同的宇节码程序需要在不同的平台上运行,这几乎是"不可能的",只有通过中间的转换器才可以实现, JVM 就是这个转换器。 JVM 是一个抽象的计算机,和实际的计算机一样,它具有指令集并使用不同的存储区域。 它负责执行指令,还要管理数据、内存和寄存器。

相关信息

生活中常见的数据线接口有 type-c 的、USB 的、lightning 8pin 的(iPhone)等等。这些数据线向下的接口五花八门,用来适应不同的设备,但向上的接口就只有一种,不同手机可以使用同一个充电头充电或者使用同一个 USB 接口连接电脑。

将不同的设备比作不同的操作系统(Window、Mac、Linux),数据线就是一个 Java 的字节码程序,数据线向下的那些五花八门的接口就是转换器。

可以认为 JVM 分为向上和向下两个部分,所有平台上的 JVM 向上提供给 Java 字节码程序的接口完全相同,但向下适应不同平台的接口则互不相同 。

Oracle 公司制定的 Java 虚拟机规范在技术上规定了 JVM 的统一标准,具体定义了 JVM 的如下细节:

  1. 指令集

  2. 寄存器

  3. 类文件的格式

  4. 垃圾回收堆

  5. 存储区

Oracle 公司制定这些规范的目的是为了提供统一的标准,最终实现 Java 程序的平台无关性。

开发 Java 的准备

在开发 Java 程序之前,必须先完成一些准备工作,也就是在计算机上安装并配置 Java 开发环境, 开发 Java 程序需要安装和配置 JDK。

下载和安装 Java 的 JDK

JDK 的全称是 Java SE Development Kit,即 Java 标准版开发包,是 Oracle 提供的一套用于开发 Java 应用程序的开发包,它提供了编译、运行 Java 程序所需的各种工具和资源,包括 Java 编译器、 Java 运行时环境,以及常用的 Java 类库等。

Java 运行时环境:它的全称是 Java Runtime Environment,因此也被称为 JRE ,它是运行 Java 程序的必需条件。

一些相关术语。

image-20220516213345296

JRE 包含 JVM 。 JVM 是运行 Java 程序的核心虚拟机,而运行 Java 程序不仅要核心虚拟机,还需要其他的类加载器、字节码校验器以及大量的基础类库。JRE 还包含运行 java 程序的其他环境支持。

一般而言,如果只是运行 Java 程序,可以只安装 JRE,无须安装 JDK。

提示

开发 Java 程序应该选择安装 JDK; JDK 包含了 JRE ,也可以运行 Java 程序 。

Oracle 把 Java 分为 Java SE、 Java EE 和 Java ME 三个部分,当前只需要 Java SE ,因此下载标准的 JDK 即可。

JDK 8 官网链接:Java Downloads | Oracleopen in new window

阿里云盘分享:jdk-8u241-windows-x64.exeopen in new window

提示

JDK 版本并不追求新,而是追求稳,如今的 JDK 更新非常快,高版本可能会出现适配性的问题。

JDK 8 ,11。

image-20220516213514572

64 位 Windows 系统的 JDK 下载成功后,得到一个 jdk-8*windows-x64* bin.exe 文件,这是一个标准的 EXE 文件,可以通过双击该文件来运行安装程序。

开始安装后,第一个对话框询问用户是否准备开始安装 JDK,单击"下一步"按钮,进入如图所示的组件选择窗口。

image-20220516213606964

开发工具:这是 JDK 的核心, 包括编译 Java 程序必需的命令工具。这个选项里己经包含了运行 Java 程序的 JRE,这个 JRE 会安装在 JDK 安装目录的子目录里,这也是无须安装公共 JRE 的原因 。

源代码:安装这个选项将会安装 Java 所有核心类库的源代码。

相关信息

公共 JRE 是一个独立的 JRE 系统,会单独安装在系统的其他路径下,公共 JRE 会向 IE 等浏览器和系统中注册 Java 运行时环境。通过这种方式。系统中任何应用程序都可以使用公共 JRE。由于现在的网页上执行 Applet 的机会越来越少,而且完全可以使用 JDK 目录下的 JRE 来运行 Java 程序,因此没有必要安装公共 JRE。

较高版本的 JDK 安装程序已经没有公共 JRE 这个组件了。

系统默认安装在 C:\Program Files\Java 路径下 , 但不推荐安装在有空格的路径下,这样可能导致一些未知的问题。

安装完成后,可以在 JDK 安装路径下看到如下的文件路径。

  1. bin: 该路径下存放了 JDK 的各种工具命令,常用的 Javac 、 Java 等命令就放在该路径下。
  2. conf: 该路径下存放了 JDK 的相关配置文件。
  3. include: 存放一些平台特定的头文件。
  4. jre:该路径下安装的就是运行 Java 程序所必需的 JRE 环境。
  5. lib: 该路径下存放的是 JDK 工具的一些补充 JAR 包。 比如 SRC . ZIP 文件中保存了 Java 的源代码。
  6. README 和 COPYRIGHT 等说明性文档。

相关信息

用于编译 Java 程序所使用的 javac.exe 命令同样也是使用 Java 编写的,这个类就是 lib 路径下 tools.jar 文件中 sun\tools\javac 路径下的 Main 类,JDK 的 bin 路径下的 javac.exe 命令实际上仅仅是包装了这个 Java 类。不仅如此,bin 路径下的绝大部分命令都是包装了 tools.jar 文件里的工具类。

不同版本安装完成后的文件数量会有差异。

设置 PATH 环境变量

编译和运行 Java 程序必须经过两个步骤

  1. 将源文件编译成字节码
  2. 解释执行平台无关的字节码程序

上面这两个步骤分别需要使用 java 和 javac 两个命令,按住 win + R 输入 cmd 启动 Windows 操作系统的命令行窗口,在命令行窗口里依次输入 java 和 javac 命令,将看到如下输出:

image-20220516213631017

这是因为:虽然我们已经在计算机里安装了 JDK,而 JDK 的安装路径下也包含了 java 和 javac 两个命令,但计算机不知道到哪里去找这两个命令。

Windows 操作系统根据 Path 环境变量来查找命令。Path 环境变量的值是一系列路径,Windows 操作系统将在这一系列的路径中依次查找命令,如果能找到这个命令,则该命令是可执行的;否则将出现“'xxx'不是内部或外部命令,也不是可运行的程序或批处理文件”的提示。

因为 Windows 操作系统不区分大小写,设置 Path 和 PATH 并没有区别。

右击桌面上“我的电脑”图标,出现右键菜单;单击“属性”菜单项,出现“系统属性”对话框;单击该对话框的“高级”Tab 页。

image-20220516213650274

单击“环境变量”按钮,将看到“环境变量”对话框,通过该对话框可以修改或添加环境变量。

image-20220516213714941

“用户变量”部分用于设置当前用户的环境变量,下面的“系统变量”部分用于设置整个系统的环境变量。对于 Windows 系统而言,名为 Path 的系统环境变量已经存在。

在系统变量中新建一个环境变量,变量名为“JAVA_HOME”,变量值为 JDK 的安装路径。该变量的作用可以理解为:为 JDK 的安装路径取了个别名,这里名字不能乱取。

image-20220516213735833

编辑 path 变量,将刚刚新建的变量添加进去。

image-20220516213755354

也可以选择直接将“D:\jdk\bin”直接加入到 path 变量,但是不推荐,会为以后的学习造成麻烦(Maven)。

提示

用户变量和系统变量并没有太大的差别,只是用户变量只对当前用户有效,而系统变量对所有用户有效。

为了减少自己所做的修改对其他人的影响,故设置用户变量避免影响其他人。

对于当前用户而言,设置用户变量和系统变量的效果大致相同,只是系统变量的路径排在用户变量的路径之前。

这可能出现一种情况:如果 PATH 系统变量的路径里包含了 java 命令,而 PATH 用户变量的路径里也包含了 java 命令,则优先执行 PATH 系统变量路径里包含的 java 命令。

保存所做的设置,之后新打开的所有控制台窗口都会有正确的路径。测试设置是否正确:重新打开一个 cmd 窗口,输入:

image-20220516213815552

然后按回车键。应该能看到显示以下信息:

image-20220516213837442

如果直接在命令行窗口里输入 javac,不跟任何选项和参数,系统将会输出大量提示信息,用以提示 javac 命令的用法,可以参考该提示信息来使用 javac 命令。

image-20220608161508584

关于 CLASSPATH

很多地方在设置 java 环境变量的时候都会介绍对 CLASSPATH 环境变量的设置,但都没有说明为什么。

实际上,如果使用 1.5 以上版本的 JDK,完全可以不用设置 CLASSPATH 环境变量——正如上面编译、运行 Java 程序所见到的,即使不设置 CLASSPATH 环境变量,完全可以正常编译和运行 Java 程序。

当使用“java Java 类名”命令来运行 Java 程序时, JRE 到当前路径下去搜索 Java 类。但 1.4 以前版本的 JDK 都没有设计这个功能,这意味着即使当前路径已经包含了 HelloWorld.class,并在当前路径下执行“java HelloWorld”,系统将一样提示找不到 HelloWorld 类。

如果使用 1.4 以前版本的 JDK,则需要在 CLASSPATH 环境变量中添加一点.,用以告诉 JRE 需要在当前路径下搜索 Java 类。除此之外,编译和运行 Java 程序还需要 JDK 的 lib 路径下 dt.jar 和 tools.jar 文件中的 Java 类,因此还需要把这两个文件添加到 CLASSPATH 环境变量里。