Java 介于编译型语言和解释型语言之间。编译型语言如 C、C++,代码是直接编译成机器码执行,但是不同的平台(x86、ARM 等)CPU 的指令集不同,因此,需要编译出每一种平台的对应机器码。解释型语言如 Python、Ruby 没有这个问题,可以由解释器直接加载源码然后运行,代价是运行效率太低。而 Java 是将代码编译成一种“字节码”,它类似于抽象的 CPU 指令,然后,针对不同平台编写虚拟机,不同平台的虚拟机负责加载字节码并执行,这样就实现了“一次编写,到处运行”的效果。当然,这是针对 Java 开发者而言。对于虚拟机,需要为每个平台分别开发。为了保证不同平台、不同公司开发的虚拟机都能正确执行 Java 字节码,SUN 公司制定了一系列的 Java 虚拟机规范。从实践的角度看,JVM 的兼容性做得非常好,低版本的 Java 字节码完全可以正常运行在高版本的 JVM 上。
Java SE:Standard Edition
Java EE:Enterprise Edition
Java ME:Micro Edition
Java SE 就是标准版,包含标准的 JVM 和标准库,而 Java EE 是企业版,它只是在 Java SE 的基础上加上了大量的 API 和库,以便方便开发 Web 应用、数据库、消息服务等,Java EE 的应用使用的虚拟机和 Java SE 完全相同。Java ME 就和 Java SE 不同,它是一个针对嵌入式设备的“瘦身版”,Java SE 的标准库无法在 Java ME 上使用,Java ME 的虚拟机也是“瘦身版”。
Java SE 是整个 Java 平台的核心,而 Java EE 是进一步学习 Web 应用所必须的。我们熟悉的 Spring 等框架都是 Java EE 开源生态系统的一部分。不幸的是,Java ME 从来没有真正流行起来,反而是 Android 开发成为了移动平台的标准之一,因此,没有特殊需求,不建议学习 Java ME。
首先要学习 Java SE,掌握 Java 语言本身、Java 核心开发技术以及 Java 标准库的使用;
如果继续学习 Java EE,那么 Spring 框架、数据库开发、分布式架构就是需要学习的;
如果要学习大数据开发,那么 Hadoop、Spark、Flink 这些大数据平台就是需要学习的,他们都基于 Java 或 Scala 开发;
如果想要学习移动开发,那么就深入 Android 平台,掌握 Android App 开发。
JDK:Java Development Kit
JRE:Java Runtime Environment
JRE 就是运行 Java 字节码的虚拟机。但是,如果只有 Java 源码,要编译成 Java 字节码,就需要 JDK,因为 JDK 除了包含 JRE,还提供了编译器、调试器等开发工具。
JSR 规范:Java Specification Request
JCP 组织:Java Community Process
JSR 是一系列的规范,从 JVM 的内存模型到 Web 程序接口,全部都标准化了。而负责审核 JSR 的组织就是 JCP。
RI:Reference Implementation
TCK:Technology Compatibility Kit
RI 只是一个“能跑”的正确的代码,它不追求速度,所以,如果真正要选择一个 Java 的消息服务器,一般是没人用 RI 的,大家都会选择一个有竞争力的商用或开源产品。
Windows 优先选x64 MSI Installer
,Linux 和 macOS 要根据自己电脑的 CPU 是 ARM 还是 x86 选择合适的安装包。
安装完 JDK 后,需要设置一个JAVA_HOME
的环境变量,它指向 JDK 的安装目录。在 Windows 下,它是安装目录,类似:
C:\Program Files\Java\jdk-21
在 Mac 下,它在~/.bash_profile
或~/.zprofile
里,它是:
export JAVA_HOME=`/usr/libexec/java_home -v 21`
然后,把JAVA_HOME
的bin
目录附加到系统环境变量PATH
上。在 Windows 下,它长这样:
Path=%JAVA_HOME%\bin;<现有的其他路径>
在 Mac 下,它在~/.bash_profile
或~/.zprofile
里,长这样:
export PATH=$JAVA_HOME/bin:$PATH
把JAVA_HOME
的bin
目录添加到PATH
中是为了在任意文件夹下都可以运行jav
a。打开命令提示符窗口,输入命令java -version
,如果一切正常,你会看到如下输出:
D:\VMware\VMware Workstation\bin>java -version
java version "17.0.9" 2023-10-17 LTS
Java(TM) SE Runtime Environment (build 17.0.9+11-LTS-201)
Java HotSpot(TM) 64-Bit Server VM (build 17.0.9+11-LTS-201, mixed mode, sharing)
如果你看到的版本号不是21
,而是17
、1.8
之类,说明系统存在多个 JDK,且默认JDK
不是JDK 21
,需要把JDK 21
提到PATH
前面。
java
:这个可执行程序其实就是 JVM,运行Java
程序,就是启动JVM
,然后让JVM
执行指定的编译后的代码;
javac
:这是 Java 的编译器,它用于把Java
源码文件(以.java
后缀结尾)编译为Java
字节码文件(以.class
后缀结尾);
jar
:用于把一组.class
文件打包成一个.jar
文件,便于发布;
javadoc
:用于从Java
源码中自动提取注释并生成文档;
jdb
:Java
调试器,用于开发阶段的运行调试。
public class Hello {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
定义被称为class
(类),这里的类名是Hello
,大小写敏感,class
用来定义一个类,public
表示这个类是公开的,public
、class
都是Java
的关键字,必须小写,Hello
是类的名字,按照习惯,首字母H
要大写。而花括号{}
中间则是类的定义。
方法是可执行的代码块,一个方法除了方法名main
,还有用()
括起来的方法参数,这里的main
方法有一个参数,参数类型是String[]
,参数名是args
,public
、static
用来修饰方法,这里表示它是一个公开的静态方法,void
是方法的返回类型,而花括号{}
中间的就是方法的代码,方法的代码每一行用;
结束。
Java 规定,某个类定义的public static void main(String[] args)
是Java
程序的固定入口方法,因此,Java
程序总是从main
方法开始执行。
Java
源码的缩进不是必须的,但是用缩进后,格式好看,很容易看出代码块的开始和结束,缩进一般是 4 个空格或者一个tab
。
当我们把代码保存为文件时,文件名必须是Hello.java
,而且文件名也要注意大小写,因为要和我们定义的类名Hello
完全保持一致。
Java
源码本质上是一个文本文件,我们需要先用javac
把Hello.java
编译成字节码文件Hello.class
,然后,用java
命令执行这个字节码文件。
可执行文件javac
是编译器,而可执行文件java
就是虚拟机。
第一步,在保存Hello.java
的目录下执行命令javac Hello.java
;
第二步,执行Hello.class
,使用命令java Hello
;
给虚拟机传递的参数Hello
是我们定义的类名,虚拟机自动查找对应的class
文件并执行。
直接运行java Hello.java
也是可以的;这是Java
11 新增的一个功能,它可以直接运行一个单文件源码!
在实际项目中,单个不依赖第三方库的Java
源码是非常罕见的,所以,绝大多数情况下,我们无法直接运行一个Java
源码文件,原因是它需要依赖其他的库。
一个Java
源码只能定义一个public
类型的class
,并且class
名称和文件名要完全一致;
使用javac
可以将.java
源码编译成.class
字节码;
使用java
可以运行一个已编译的Java
程序,参数是类名。