菜单

Java 基础

相关源文件

目的与范围

本文档涵盖了 Java 编程语言的基础概念,重点关注核心语言特性、执行环境、语法基础、数据类型和基本编程结构。它为理解 JavaGuide 仓库中更高级的 Java 主题奠定了基础。有关 Java 集合框架的信息,请参阅 Java 集合,有关并发主题,请参阅 Java 并发

Java 简介

Java 是一种高级、面向类、面向对象的编程语言,其设计旨在最大限度地减少实现依赖。它以“一次编写,随处运行”的能力而闻名,这意味着 Java 代码可以在所有支持 Java 的平台上运行,而无需重新编译。

Java 语言特性

Java 具有多项关键特性,这些特性促成了其广泛的应用。

  1. 语法简洁且熟悉 - 易于学习,尤其是对于熟悉 C/C++ 的程序员。
  2. 面向对象 - 基于包含数据和方法的对象的概念。
  3. 平台无关性 - Java 虚拟机 (JVM) 可实现跨平台功能。
  4. 多线程支持 - 内置支持并发编程的语言。
  5. 可靠性 - 强大的异常处理和自动内存管理。
  6. 安全性 - 多重安全特性和受限的直接内存访问。
  7. 高性能 - 即时 (JIT) 编译和其他优化。
  8. 网络友好 - 全面的网络编程支持。
  9. 编译型和解释型 - 在执行中使用编译和解释。

虽然“一次编写,随处运行”曾经是 Java 最重要的卖点,但如今 Java 强大的生态系统和广泛的库被认为是其最大的优势。

来源

Java 版本

Java 主要有三个版本,每个版本都为不同的目的而设计。

版本全称目的用例
Java SEJava 平台,标准版核心平台,基线 API桌面应用程序,简单的服务器应用程序
Java EEJava 平台,企业版基于 Java SE 构建的企业功能Web 应用程序,分布式企业应用程序
Java MEJava 平台,微型版适用于小型设备的 API嵌入式系统,移动设备(历史)

Java SE 是其他版本的基础。Java EE(现为 Jakarta EE)增加了企业功能,如 Servlet、JSP、EJB、JDBC、JPA、JMS 等。Java ME 是用于资源受限设备的专用版本,但在现代开发中已不太常见。

来源

Java 运行时环境

JVM、JDK 和 JRE 解释

这三个组件构成了 Java 执行环境的核心。

  • JVM (Java Virtual Machine,Java 虚拟机):这是 Java 的运行时引擎,负责执行 Java 字节码。不同的操作系统有自己的 JVM 实现,但它们都执行相同的字节码,从而确保了平台无关性。

  • JRE (Java Runtime Environment,Java 运行时环境):包含运行 Java 应用程序所需的 JVM 和标准类库。如果用户只想运行 Java 程序,通常只需要 JRE。

  • JDK (Java Development Kit,Java 开发工具包):JRE 的超集,其中包含开发工具,如编译器 (javac)、文档生成器 (javadoc) 和调试器 (jdb)。开发人员使用 JDK 来创建 Java 应用程序。

从 JDK 9 开始,由于模块系统的引入,JDK 和 JRE 之间的传统区别变得不那么重要了,该系统允许创建仅包含必需模块的自定义运行时映像。

来源

字节码与执行流程

Java 程序经过独特的编译和执行流程。

  1. Java 源代码(.java 文件)由 Java 编译器 (javac) 编译成字节码(.class 文件)。
  2. 字节码是平台无关的,可以在任何装有 JVM 的系统上执行。
  3. JVM 加载字节码,进行验证,并通过解释执行。
  4. 即时 (JIT) 编译器会识别频繁执行的代码(“热点”),并将其编译成本地机器码以提高性能。

这种混合方法结合了解释器的平台无关性和编译器的性能优势,使得 Java 既具有可移植性又相当快速。

来源

AOT 与 JIT 编译

Java 支持两种主要的编译方法。

功能JIT(即时编译)AOT(提前编译)
编译发生时间运行时执行前
内存使用较高较低
启动时间更慢更快
峰值性能较高较低
动态特性支持完全支持有限支持
用例传统 Java 应用程序微服务、Serverless、容器

AOT 编译(JDK 9 引入,并由 GraalVM 增强)提供了更快的启动和更低的内存占用等优势,特别适合云原生部署。但是,它在 Java 的反射、动态代理和类加载等动态特性方面存在一些限制。

来源

Oracle JDK vs OpenJDK

有两种主要的 JDK 分发版可供选择。

方面Oracle JDKOpenJDK
许可商业许可,带有免费选项开源 (GPL v2)
发布周期更长的发布周期,LTS 版本更频繁的发布
支持提供商业支持社区支持
特性可能包含额外的专有功能完全开源
稳定性通常被认为对生产环境更稳定稳定,但可能需要更多测试

自 Java 11 起,Oracle JDK 基于 OpenJDK 代码构建,差异很小。许多公司现在提供自己的 OpenJDK 分发版,带有长期支持,例如 Amazon Corretto、Azul Zulu 和 AdoptOpenJDK。

来源

Java 语法基础

注释

Java 支持三种注释类型。

文档注释尤其重要,因为它们可以被 javadoc 工具处理以生成 API 文档。良好的注释习惯有助于提高代码的可读性和可维护性,尽管简洁且自文档化的代码可以减少对大量注释的需求。

来源

标识符和关键字

  • 标识符:为变量、方法、类等命名的名称。必须以字母、下划线或美元符号开头,后跟字母、数字、下划线或美元符号。

  • 关键字:在语言中具有特殊含义的保留字,不能用作标识符。

Java 具有以下关键字。

类别关键字
访问控制privateprotectedpublic
类、方法、变量修饰符abstractclassextendsfinalimplementsinterfacenativenewstaticstrictfpsynchronizedtransientvolatileenum
程序控制breakcontinuereturndowhileifelseforinstanceofswitchcasedefaultassert
错误处理trycatchthrowthrowsfinally
包相关importpackage
基本类型booleanbytechardoublefloatintlongshort
变量引用superthisvoid
保留字gotoconst

请注意,truefalsenull 是字面量,不是关键字,但它们也不能用作标识符。

来源

运算符

Java 提供了几种类型的运算符。

自增/自减运算符

运算符 ++-- 可以以前缀或后缀形式使用。

  • 前缀形式(++a--a):先增/减,然后使用该值。
  • 后缀形式(a++a--):先使用当前值,然后增/减。

位运算符

位运算符用于位级操作,包括:

  • <<:左移(乘以 2 的幂)。
  • >>:有符号右移(除以 2 的幂)。
  • >>>:无符号右移(用零填充)。
  • &:按位与。
  • |:按位或。
  • ^:按位异或。
  • ~:按位取反。

位操作对于某些任务(如标志操作、权限和底层操作)非常高效。

来源

控制流语句

Break、Continue 和 Return

  • break:终止循环或 switch 语句的执行。
  • continue:跳过当前迭代,继续进行循环的下一个迭代。
  • return:退出当前方法,可以选择性地返回值。

来源

Java 中的数据类型

基本数据类型

Java 有八种基本数据类型。

类型大小范围默认值
byte1 字节-128 到 1270
short2 字节-32,768 至 32,7670
int4 字节-2^31 至 2^31-10
long8 字节-2^63 至 2^63-10L
浮点数4 字节~±3.40282347E+38F0.0f
double8 字节~±1.7976931348623157E+3080.0d
char2 字节0 至 65,535'\u0000'
布尔值-true 或 falsefalse

重要提示

  • 长整型文字必须加上后缀 L(例如 100L)。
  • 单精度浮点型文字必须加上后缀 F(例如 3.14F)。
  • 字符文字使用单引号(例如 'A')。
  • 字符串文字使用双引号(例如 "Hello")。

来源

基本类型与包装类

Java 中的每种基本类型都有一个对应的包装类。

基本类型包装类
byteByte
short短期
int整型
long长期
浮点数浮点数
doubleDouble
charCharacter
布尔值布尔值

基本类型和包装类之间的主要区别

  1. 内存占用:基本类型比其对应的包装类占用更少的内存。
  2. Nullability:基本类型不能为 null,而包装类对象可以。
  3. 在集合中的使用:泛型集合(如 ArrayList<Integer>)需要包装类,而非基本类型。
  4. 方法:包装类提供了用于转换和操作的实用方法。
  5. 默认值:基本类型有默认值,包装类变量默认为 null

来源

装箱与拆箱

Java 提供了原始类型与其包装类之间的自动转换

  • 装箱:从原始类型到包装类的自动转换(例如,intInteger
  • 拆箱:从包装类到原始类型的自动转换(例如,Integerint

虽然方便,但频繁的装箱和拆箱会影响性能,尤其是在循环或高吞吐量的应用程序中。

来源

包装类缓存

Java 的包装类对常用值实现了缓存机制

  • ByteShortIntegerLong:缓存 -128 到 127 范围内的值
  • Character:缓存 0 到 127 范围内的值
  • Boolean:只有两个实例(TRUEFALSE
  • FloatDouble:没有缓存机制

这种缓存解释了以下代码为何会产生此行为

最佳实践是使用 equals() 方法来比较包装类对象。

来源

浮点数精度问题

浮点类型(floatdouble)由于其在二进制中表示小数的方式,可能存在精度问题

为了精确的十进制计算,尤其是在金融应用中,请使用 BigDecimal 代替

请注意,BigDecimal 应使用 String 参数来构造,而不是浮点数值,以避免继承精度问题。

来源

Java中的变量

变量的类型

Java有三种类型的变量

  1. 局部变量:在方法、构造函数或代码块内声明。使用前必须初始化,且在作用域外不可访问。

  2. 实例变量(非静态字段):在类中声明但在方法外。类的每个对象都有自己的这些变量副本。如果未显式初始化,它们可以具有默认值。

  3. 类变量(静态字段):使用 static 关键字声明。它们属于类而不是任何实例,并在类的所有对象之间共享。

来源

变量的内存分配

不同类型的变量存储在不同的内存区域

  • 局部变量:存储在栈内存中
  • 实例变量:存储在堆内存中(作为对象的一部分)
  • 静态变量:存储在方法区(或新版 JVM 中的元空间)

这种内存分配方式对变量的生命周期、作用域和垃圾回收都有影响。

来源

Final 变量

final 关键字声明的变量在初始化后不能被重新赋值

对于对象,引用不能改变,但对象的状态仍然可以被修改

来源

Java 中的方法

方法类型

Java 中的方法可以根据几个标准进行分类

  1. 根据返回值类型:

    • 有返回值的方法
    • 无返回值的方法(void
  2. 根据参数:

    • 有参数的方法
    • 无参数的方法
  3. 根据 static 关键字:

    • 静态方法(属于类)
    • 实例方法(属于对象)
  4. 根据访问修饰符:

    • 公共方法
    • 私有方法
    • 保护方法
    • 包私有方法(默认)

来源

方法重载与方法重写

方法重载是指在同一类中,多个方法具有相同的名称但参数不同

方法重写是指子类提供了父类中已定义的方法的特定实现

重载与重写的关键区别

方面重载重写
发生在同一类父类与子类
参数必须不同必须相同
返回值类型可以不同必须相同或协变
访问修饰符可以更改不能更严格
异常声明可以更改只能减少或消除
绑定编译时运行时

来源

可变参数(Varargs)

Java 使用可变参数功能支持方法中可变长度的参数列表

可变参数的规则

  1. 每个方法只允许有一个可变参数
  2. 可变参数必须是方法签名中的最后一个参数
  3. 在底层,可变参数会被转换为数组

来源

结论

本文档涵盖了 Java 编程语言的基础方面,包括其特性、执行环境、语法基础、数据类型和基本编程结构。这些基础知识构成了更高级的 Java 主题,如集合、并发和 I/O 的基础,这些内容将在 JavaGuide 的其他部分介绍。

有关更高级的主题,请参阅