Java 语言的版本
- Java SE:整个 Java 技术的核心和基础,也就是 Java 编程语言的语法和核心类库。
- Java EE:Java EE 提供了企业应用开发相关的完整解决方案。
- Java ME:主要用于控制移动设备和信息家电等有限存储的设备。
Oracle约定每三年发布一个长期支持(LST)的版本,比如 Java 9、Java 10 都不是 LTS 版本,只是“功能性的版本”,Oracle 只提供半年的技术支持。Java 11 是 Java 8 之后第一个 LTS 版本,直到 2023 年 Oracle 都会为 Java 11 提供技术支持。
Java 1.2 对 API 进行了分类:
- 核心 API:Java 平台提供的基本 API,就是平常所说的核心类库。
- 可选 API:为 JDK 扩充的 API,因平台的不同而不同。
- 特殊 API:满足特殊要求的 API,例如 JCA 和 JCE 第三方加密类库。
Java 程序的运行机制和 JVM
Java 程序的执行过程是先编译,后解释。
用 Java 语言编写的源程序,先经过 Java 编译器(javac 命令)生成一种与平台无关的字节码,即 .class 文件。字节码不是可执行的,必须使用 Java 解释器来解释执行。所以,Java 既是编译型语言,也是解释型语言。
负责解释执行字节码文件的是 Java 虚拟机,即 JVM(Java Virtual Machine),它是可运行 Java 字节码文件的虚拟计算机,具有指令集并使用不同的存储区域,负责执行指令,并管理数据、内存和寄存器。
Java 语言的跨平台性体现在:只需要提供特定平台的 Java 虚拟机,就能解释执行相同的字节码。这一点与解释型语言类似,例如 Python,只需提供 Windows 和 Linux 各自实现的 Python 解释器,就能对同一份 Python 源程序进行解释执行。
Oracle 公司制定了 JVM 的技术规范,包含的细节:
- 指令集
- 寄存器
- 类文件的格式
- 栈
- 垃圾回收器 GC
- 存储区
Java 开发环境
JDK、JRE 和 JVM
JDK(Java SE Development Kit)是 Java 标准版开发包,是 Oracle 提供的一套用于开发 Java 应用程序的开发包,提供了编译、运行 Java 程序所需的各种工具和资源,包括 Java 编译器、Java 运行时环境,以及常用的 Java 类库等。安装的 JDK 本身包含 JRE。
JRE(Java Runtime Environment) 即 Java 运行时环境,用于运行 Java 程序。
如果仅仅是运行 Java 程序,只需用 JRE;如果是开发 Java 程序,就需要安装 JDK。
JRE 包括 JVM,JVM 是运行 Java 程序的核心虚拟机。除此之外,运行 Java 程序还需要类加载器、字节码校验器以及大量的基础类库。JRE 除了提供 JVM,还需要提供这些环境支持。
JDK 目录介绍
安装了 Java 11 的 JDK 后,其安装路径包含的文件:
- bin:存放 JDK 的各种工具命令,包括 java、javac、jshell 等。
- conf:存放 JDK 的相关配置文件。
- include:存放一些平台特定的头文件。
- jmods:存放 JDK 的各种模块。
- legal:存放 JDK 各模块的授权文档。
- lib:存放 JDK 工具的一些补充 JAR 包,例如 src.zip 文件中保存了 Java 的源代码。
- README 和 COPYRIGHT 等说明性文档。
自从 Java 9 之后,Java 语言提供了模块化系统,允许发布的 Java 软件只加载必要的模块,JMOD 就是为此引入的新格式。例如 jmods 目录的 java.base.jmod 文件用 7z 打开:
可以发现,这个 JMOD 模块是基础模块,包含一些常用的模块。
PATH 和 CLASSPATH
PATH
安装完 JDK 后,需要将安装路径下的 bin 目录路径添加到 PATH 环境变量中。Windows 和 Linux 的环境变量设置方法是不同的,需要注意的几点:
- Windows 操作系统的环境变量不区分大小写,例如 Path 等价于 PATH。
- Windows 操作系统的用户环境变量与系统环境变量的优先级是前者小于后者。
把"JDK安装路径/bin"添加到 PATH 环境变量后,就可以在命令行窗口中执行 Java 工具命令:
CLASSPATH
CLASSPATH 环境变量的作用是当执行“java 类名”命令时,JRE 从CLASSPATH 指定的路径搜索 Java 类。在 Java 1.4 以前版本的 JDK,需要在 CLASSPATH 环境变量中添加点(.),告诉 JRE 在当前路径下搜索 Java 类。
除此之外,还需要添加 JDK 的 lib 路径下的 dt.jar 和 tools.jar 两个文件路径到 CLASSPATH 环境变量中。但是,Java 11 的 lib 目录已经不再包含 dt.jar 和 tools.jar 文件,并且执行"java 类名"命令,JRE 也会默认从当前路径下搜索类名。
当然,Java 1.5 以上版本的 JDK 也可以设置 CLASSPATH 环境变量,一旦设置了它,JRE 就会按照它所指定的路径去搜索 Java 类,如果没有点(.),JRE 就不会在当前路径下搜索。所以,建议非必要不设置 CLASSPATH。
运行 Java 程序时可以用 -classpath(-cp) 参数指定 JRE 搜索 Java 类的路径:
java -classpath dir1;dir2;dir3 Java类名
java -classpath %CLASSPATH%;.;dir1;dir2;dir3 Java类名 # 加入点和 CLASSPATH 环境变量
一旦指定了 -classpath 参数,JRE 就不会在当前路径下搜索 Java 类,CLASSPATH 环境变量也会失效。(可以在参数值中补充上去)
执行第一个 Java 程序
编译
当打开一个文本编辑器,创建一个文件 HelloWorld.java,编写如下代码:
public class HelloWorld
{
// Java 程序的入口方法,程序将从这里开始执行
public static void main(String[] args)
{
// 向控制台打印一条语句
System.out.println("Hello World!");
}
}
在当前路径下,执行命令:javac -d . HelloWorld.java
-d 指定字节码文件的生成路径,这里是点(.),即当前路径,HelloWorld.java 是 Java 源程序文件。
当省略 -d 时,即 javac HelloWorld.java,默认也是在当前路径下生成字节码文件。
上面的命令执行后,在当前路径下生成 HelloWorld.class。要注意的是,生成的字节码文件以源程序文件所定义的类名作为主文件名,以 .class 为扩展名。如果源程序文件定义了多个类,那么就会生成多个 .class 文件。例如一个源程序文件的代码如下:
class Dog
{
}
class Item
{
}
class Category
{
}
编译后会生成三个字节码文件:Dog.class、Item.class、Category.class。
执行
编译生成字节码后,就可以调用 JVM 解释执行 Java 程序了。运行 Java 程序使用 java 命令,对上述生成的 HelloWorld.class 在其路径下执行:java HelloWorld
特别注意,并不需要加 .class 扩展名。
Java 程序的基本规则
Java 程序的组织形式
Java 程序是一种纯粹的面向对象的程序设计语言,因此 Java 程序必须以类(class)的形式存在,类是 Java 程序的最小程序单元。Java 程序不允许可执行性语句、方法等成分独立存在,所有的程序部分都必须放在类定义里。
最简单的 Java 程序仅包括一个类定义:
class Test
{
}
用 javac 命令编译没有问题,但用 java 命令执行时,就会出现如下错误提示:
这是 Java 语言规定,如果要直接解释执行某个类,该类必须定义 main 方法,并且被 public static 修饰,使用 void 声明该方法的返回值,形参必须是字符串数组类型(String[] args)。这个 main 方法就是作为程序执行的入口。
Java 源文件的命名规则
规则如下:
- Java 程序源文件的扩展名必须是 .java。
- 主文件名可以是任意,但如果 Java 程序源代码中定义了一个 public 类,则该源文件的主文件名必须与该 public 类的类名相同。
因此,一个 Java 源文件最多只能定义一个 public 类。
一个 Java 源文件可以定义多个类,这样生成的字节码文件也会有相应的个数。
为了更好的可读性,建议:
- 一个 Java 源文件通常只定义一个类,不同的类使用不同的源文件定义。
- 让 Java 源文件的主文件名与该源文件中定义的 public 类或者仅有的那个非 public 类同名。
交互式工具 jshell
jshell 是一个交互式工具,类似于在控制台中输入 python,可用于测试一些代码片段或者新 API。
在控制台输入:jshell,然后输入 /help 查看帮助信息: