Java——JavaSE完整教程

文章目录


前置知识

字节

  • 位(bit)
    是计算机内部数据存储的最小单位,只有 0 和 1 两种状态,用来表示一个二进制数位。例如 11001100 就是一个 8 位的二进制数。
  • 字节(byte)
    是计算机中数据处理的基本单位,习惯上用大写 B 表示。
    换算关系:1B = 8bit,即 1 个字节由 8 个二进制位组成。
  • 字符
    指计算机中使用的字母、数字、文字和符号,比如 A、5、中、! 都属于字符。

存储单位换算

计算机存储容量的标准换算关系:
1Byte = 8bit
1024B = 1KB
1024KB = 1MB
1024MB = 1GB

转义字符

Java 转义字符以反斜杠 \ 开头,用于表示特殊字符或无法直接输入的字符(如换行、制表符等)。以下是常见转义字符及其用途。

常见转义字符列表

  • \t:水平制表符(Tab)
  • \n:换行符(Newline)
  • \r:回车符(Carriage Return)
  • \\:反斜杠本身
  • \":双引号(用于字符串内)
  • \':单引号(用于字符内)
  • \b:退格符(Backspace)
  • \f:换页符(Form Feed)
java 复制代码
public class EscapeSequences {
    public static void main(String[] args) {
        System.out.println("Hello\tWorld");  // 输出: Hello    World(制表符)
        System.out.println("Line1\nLine2");  // 输出: Line1 换行 Line2
        System.out.println("C:\\Program\\Java");  // 输出: C:\Program\Java
        System.out.println("He said, \"Hi\"");  // 输出: He said, "Hi"
    }
}

Unicode 转义

Java 支持 Unicode 转义,格式为 \uXXXX(4位十六进制数)。例如:

java 复制代码
System.out.println("\u03A9"); // 输出希腊字母 Ω

注意事项

  • 在正则表达式中需双重转义(如 \\d 匹配数字)。
  • 字符串中的换行符需根据操作系统调整(Windows 使用 \r\n,Linux/macOS 使用 \n)。

通过合理使用转义字符,可以处理特殊字符或格式化文本输出。

Java 简介

Java 是由Sun Microsystems(后被 Oracle 收购)于 1995 年推出的面向对象、跨平台高级编程语言,由詹姆斯・高斯林(James Gosling)及其团队研发,核心设计理念围绕 "简单、安全、跨平台、高性能" 展开,目前已成为全球最主流的编程语言之一,广泛应用于企业级开发、移动开发、大数据等多个领域。

一、Java 核心三大特性(核心设计基石)

Java 的跨平台能力和核心优势,核心依托于三大核心特性,也是其区别于其他语言的关键:

  1. 一次编写,到处运行(Write Once, Run Anywhere - WORA)
    这是 Java 最标志性的特性,实现原理是Java 程序并非直接编译为操作系统的机器码,而是先由 javac 编译器编译为与平台无关的字节码(Bytecode)(文件后缀 .class),再由不同操作系统上对应的 Java 虚拟机(JVM, Java Virtual Machine) 解释 / 编译执行字节码。
    开发者只需编写一套代码,无需针对 Windows、Linux、macOS 等不同系统做修改;
    不同系统只需安装对应的 JVM(虚拟机),即可运行相同的字节码文件,真正实现跨平台。
  2. 面向对象(Object-Oriented, OOP)
    Java 是纯面向对象的编程语言(除基本数据类型外,一切皆对象),完全遵循面向对象的四大核心原则:封装、继承、多态、抽象,通过类(Class)和对象(Object)组织代码,大幅提升代码的可复用性、可维护性和扩展性,适合开发大型、复杂的软件系统。
  3. 自动内存管理(垃圾回收 - Garbage Collection, GC)
    Java 摒弃了 C/C++ 中手动管理内存的方式(手动malloc分配 /free释放),由 JVM 的垃圾回收器 自动监控并回收程序中不再使用的内存空间(无引用的对象),从根源上减少了内存泄漏和空指针异常等常见内存问题,降低了开发门槛和程序出错概率。
    注:开发者可通过 JVM 参数调优垃圾回收策略,平衡内存使用和程序性能。

二、Java 技术体系(三大核心平台,覆盖全开发场景)

Java 并非单一语言,而是一套完整的技术体系,根据应用场景分为三大核心平台,适配从嵌入式到大型分布式系统的所有开发需求:

  1. Java SE(Java Standard Edition - 标准版)核心基础
    Java 技术的基础核心,包含 Java 核心语法、基础类库(集合、IO、多线程、网络编程等)、JVM、编译器等核心组件,是其他两个平台的基础。主要用于开发桌面应用(如 Swing/JavaFX 程序)、控制台程序,以及为 Java EE/Java ME 提供底层支持。
  2. Java EE(Java Platform, Enterprise Edition - 企业版)
    基于 Java SE 扩展的企业级开发平台,提供了一系列针对企业级应用的标准和技术规范(如 Servlet、JSP、EJB、Spring、MyBatis 等),专门用于开发分布式、高可用、高并发的企业级应用,如电商平台、金融系统、后台管理系统、大型网站后端等,是 Java 在企业开发领域的核心应用方向。
  3. Java ME(Java Micro Edition - 微型版)基本不用
    基于 Java SE 精简的嵌入式 / 移动开发平台,针对资源受限的设备(如嵌入式设备、智能家电、早期功能手机)设计,核心是轻量级的类库和 JVM。随着 Android 的兴起,其移动开发场景逐渐被替代,但仍在嵌入式领域有一定应用。

三、Java 典型应用领域

依托跨平台、稳定、安全、高性能的特性,Java 的应用覆盖几乎所有软件开发领域,是工业级开发的 "主力军",主要应用场景包括:

企业级后端开发:最核心的应用领域,基于 Spring Boot、Spring Cloud 等框架开发分布式微服务系统,支撑电商、金融、政务、物流等行业的核心业务;

Android 应用开发:Android 系统的底层开发语言为 Java(目前 Kotlin 为官方推荐,但仍兼容 Java),几乎所有 Android App 的核心逻辑都可通过 Java 实现;

大数据开发:大数据生态的核心框架(Hadoop、Spark、Flink、HBase 等)均由 Java 编写,大数据开发中的核心业务逻辑开发、框架二次开发也主要使用 Java;

桌面应用开发:通过 Swing、JavaFX 等技术开发跨平台的桌面客户端(如办公软件、开发工具、工业控制软件);

嵌入式开发:基于 Java ME 开发智能家电、物联网设备、工业嵌入式系统;

云原生开发:结合 Docker、K8s、Spring Cloud Alibaba 等技术,开发云原生微服务、容器化应用。

四、Java 语言的核心优势

跨平台性:依托 JVM 和字节码,实现 "一次编写,到处运行",大幅降低多平台开发的成本;

面向对象:纯面向对象设计,代码结构清晰,可复用性和可维护性强,适合大型项目开发;

内存安全:自动垃圾回收机制,避免手动内存管理的错误,同时提供数组边界检查、空指针防护等机制,提升程序稳定性;

安全性高:内置安全管理器(Security Manager),可限制程序的资源访问(如文件、网络),同时字节码验证机制可防止恶意代码执行,适合开发金融、政务等对安全要求高的系统;

生态完善:拥有全球最丰富的开源生态,海量的第三方框架(Spring、MyBatis、Netty 等)、类库和工具,大幅提升开发效率,解决几乎所有开发场景的问题;

稳定性和高性能:经过二十多年的迭代优化,Java 虚拟机的即时编译(JIT)技术大幅提升了程序运行效率,同时语言本身的设计保证了程序的稳定性,可支撑 7×24 小时不间断运行的企业级系统;

跨领域兼容:可与 C/C++、Python、Go 等语言无缝集成,同时支持多种数据库(MySQL、Oracle、Redis 等),适配不同的技术栈;

社区和人才丰富:全球拥有庞大的开发者社区,遇到问题可快速找到解决方案;同时 Java 开发者基数大,企业易招聘到相关人才。

五、Java 版本迭代与现状

Java 自 1995 年发布以来,持续迭代优化,核心版本节点包括:

JDK 1.0(1996):首个正式版本,奠定核心语法和 JVM 基础;

JDK 5(2004):里程碑版本,引入泛型、注解、自动装箱、foreach 循环等核心特性,大幅提升开发效率;

JDK 8(2014):目前使用最广泛的 LTS(长期支持)版本,引入 Lambda 表达式、Stream API、函数式接口等,支持函数式编程,是企业开发的主流版本;

JDK 11(2018):新一代 LTS 版本,移除永久代、引入模块化(Module)、支持 HTTP/2,适合云原生开发;

JDK 17(2021):最新的主流 LTS 版本,优化模块化、增强安全性、提升性能,是目前推荐的新一代生产环境版本。

目前企业开发中,JDK 8 仍占主导地位(生态兼容最完善),JDK 11 和 JDK 17 的使用率正在快速提升,Oracle 对 LTS 版本提供长期的安全更新和技术支持,保障企业系统的稳定性。

六、Java 开发的核心环境

Java 开发的基础环境为 JDK(Java Development Kit - Java 开发工具包),它包含了开发 Java 程序所需的所有组件:

JRE(Java Runtime Environment - Java 运行时环境):包含 JVM、核心类库,是运行 Java 程序的基础(仅运行程序可只安装 JRE);

编译器(javac):将 Java 源代码(.java)编译为字节码(.class);

解释器(java):启动 JVM 并执行字节码文件;

其他工具(javadoc、jdb、javap 等):用于生成文档、调试程序、反编译字节码等。

开发者只需在电脑上安装对应系统的 JDK,配置环境变量后,即可通过命令行或 IDE(如 IntelliJ IDEA、Eclipse)进行 Java 开发。

Java 入门

JDK、JRE、JVM

JDK ⊃ JRE ⊃ JVM

  • JVM(Java Virtual Machine):最底层的执行引擎,负责加载并执行 .class 字节码文件,是实现 "一次编写,到处运行" 的核心。
    作用:屏蔽了不同操作系统的底层差异,让字节码可以在任何安装了 JVM 的系统上运行,是跨平台能力的核心。
  • JRE(Java Runtime Environment):包含 JVM 和 Java 核心类库(如集合、IO、网络等),是运行 Java 程序的必要环境。
    作用:提供了运行 Java 程序所需的基础环境,普通用户只需安装 JRE 就能运行已编译的 Java 程序。
  • JDK(Java Development Kit):在 JRE 基础上增加了开发工具(如编译器 javac、打包工具 jar、文档生成工具 javadoc 等),是开发 Java 程序的完整工具包。
    作用:面向开发者,包含了开发、编译、调试 Java 程序的所有工具,开发者必须安装 JDK 才能进行编码工作。

Java程序运行机制

Java 程序先经编译器 javac 把.java源文件编译成字节码.class文件。字节码由 JVM 加载,JVM 里类加载子系统负责找到并加载字节码,然后字节码被送到执行引擎,执行引擎可以采用解释执行(逐行解释执行字节码)或 JIT 即时编译(将频繁执行代码编译为机器码)方式运行,运行时数据区还会分配内存来存储程序运行的各种数据,像堆存对象、栈管方法调用等。

IDE

IDE 是集成开发环境(Integrated Development Environment)的简称,它把源代码编辑器、构建自动化工具、调试器等软件开发工具集成在一起,有些还包含编译器、解释器。能提高开发效率,常见的有用于 Java 开发的 Eclipse、IntelliJ IDEA 等。

第一个Java程序

java 复制代码
public class HelloJava {                                                                                                
    public static void main(String[] args){                                                                         
        System.out.print("Hello,World!");                                                                       
  }                                                                                                               
}  

public:访问修饰符,表示公共的,可被其他类访问。

class:定义类的关键字,一个 Java 程序基本单元。

HelloJava:类名,需与文件名一致(首字母大写规范)。

static:静态的,修饰方法表示可直接用类名调用。

void:表示方法无返回值。

main:主方法名,程序执行入口。

String[]:字符串数组类型。

args:数组名,可接收命令行参数 。

System:系统类,提供一些系统相关功能。

out:System类的标准输出对象。

print:输出方法,输出内容不换行。

JavaSE 基础

注释

Java中的注释有三种:
单行注释

java 复制代码
int x = 10; // 这是一个单行注释

多行注释

java 复制代码
/*
这是多行注释
可以包含多行内容
*/
System.out.println("Hello");

文档注释

java 复制代码
/**
 * 计算两个数的和
 * @param a 第一个加数
 * @param b 第二个加数
 * @return 两数之和
 */
public int add(int a, int b) {
    return a + b;
}

文档注释的标签

Java文档注释支持多种标准标签,用于规范化文档内容。常用标签包括:

  1. @param描述方法参数
java 复制代码
@param parameterName 参数说明
  1. @return描述返回值
java 复制代码
@return 返回值说明9
  1. @throws描述可能抛锚的异常
java 复制代码
@throws ExceptionType 异常说明
  1. @see创建交叉引用
java 复制代码
@see ClassName#methodName
  1. @deprecated标记已过时的方法
java 复制代码
@deprecated 替代方案说明
  1. @since指明引入文本
java 复制代码
@since versionNumber

生成API文档

使用Javadoc工具可以从文档注释生成HTML格式的API文档。在命令行运行:

bash 复制代码
javadoc -d docDir SourceFiles.java

常用Javadoc选项包括:

-d指定输出目录

-author包含作者信息

-version包含版本信息

-encoding指定字符编码

IDE如IntelliJ IDEA和Eclipse都内置Javadoc支持,可通过图形界面生成文档。生成的文档包含类层次结构、方法详细说明和交叉引用等信息。

关键字

Java关键字是编程语言中预定义的保留字,具有特定功能,不能作为变量名、类名或方法名使用。Java共有50多个关键字,分为数据类型、流程控制、访问控制等类别。

数据类型关键字

基本类型:byte、short、int、long、float、double、char、boolean

引用类型:class、interface、enum

特殊值:null、true、false

流程控制关键字

条件语句:if、else、switch、case、default

循环语句:for、while、do

跳转语句:break、continue、return

访问控制关键字

public:全局可见

protected:包内及子类可见

private:仅类内可见

default(隐式):包内可见

类与对象关键字

class:定义类

new:创建对象实例

this:当前对象引用

super:父类引用

extends:继承

implements:实现接口

instanceof:类型检查

异常处理关键字

try:捕获异常代码块

catch:处理异常

finally:最终执行块

throw:抛出异常

throws:声明可能抛出的异常

修饰符关键字

static:类级别成员

final:不可修改的变量、方法或类

abstract:抽象类或方法

synchronized:线程同步

volatile:变量可见性

transient:序列化时忽略字段

native:本地方法

其他关键字

package:定义包

import:导入类

assert:断言检查

const(未使用):保留字

goto(未使用):保留字

注意事项

关键字严格区分大小写,例如class正确,Class不是关键字。

避免与保留字冲突,如var(Java 10后作为局部变量类型推断,非严格关键字)。

数据类型

Java是强类型语言:要求变量的使用严格符合规定,所有变量都必须先定义后使用

基本数据类型(Primitive Type)

Java中的基本数据类型是预定义的,由语言本身提供,共有8种。这些类型不依赖于任何类,直接存储值。

  • 整数类型
    byte: 8位,范围-128到127
    short: 16位,范围-32,768到32,767
    int: 32位,范围-2³¹到2³¹-1
    long: 64位,范围-2⁶³到2⁶³-1(long类型后面要加L)
  • 浮点类型
    float: 32位,单精度浮点数(float类型后面要加F)
    double: 64位,双精度浮点数
  • 字符类型
    char: 16位,存储Unicode字符(一种国际字符编码标准)
    注:Unicode为全球几乎所有语言的字符、符号、表情等都分配了唯一的数字编码(码点),解决了传统编码(如 ASCII、GBK)只能表示有限字符、不同编码间不兼容的问题。
  • 布尔类型
    boolean: 存储true或false

引用数据类型(Reference Data Types)

引用数据类型指向对象的引用,而非直接存储值。这些类型基于类或接口。

  • 类类型
    String: 字符串类
    自定义类: 用户定义的类
  • 数组类型
    一维或多维数组,如int[]或String[][]
  • 接口类型
    实现接口的类的对象

数据转换

Java中的数据类型转换分为 自动类型转换(隐式转换)强制类型转换(显式转换) 两种。

自动类型转换(隐式转换)

自动类型转换发生在兼容的数据类型之间,且目标类型的范围大于源类型时,编译器会自动完成转换。

java 复制代码
int a = 100;
long b = a;  // 自动将int转换为long

自动转换规则:
byte → short → int → long → float → double
char → int → long → float → double

java 复制代码
byte byteVal = 10;
short shortVal = byteVal;  // byte自动转为short
int intVal = shortVal;     // short自动转为int
float floatVal = intVal;   // int自动转为float
double doubleVal = floatVal; // float自动转为double

注:


字符串 + xxx ,String --> 会将后面的数据转换成字符串

强制类型转换(显式转换)

当需要将范围大的数据类型转换为范围小的数据类型时,必须使用强制类型转换。语法是在变量前加上目标类型的括号

java 复制代码
long a = 1000L; // long类型后面要加L
int b = (int) a;  // 强制将long转为int

注:可能导致数据丢失或精度损失。对于超出目标类型范围的值,结果可能不符合预期。

java 复制代码
double d = 123.456;
int i = (int) d;  // i的值为123,小数部分丢失

int largeInt = 300;
byte smallByte = (byte) largeInt;  // 结果为44(300超出byte范围,发生截断)

字符串与其他类型的转换

  • 其他类型转字符串:
    使用String.valueOf()方法或直接拼接:
java 复制代码
int num = 42;
String str1 = String.valueOf(num);  // "42"
String str2 = "" + num;             // "42"
  • 字符串转其他类型:
    使用包装类的parseXxx()方法:
java 复制代码
String str = "123";
int num = Integer.parseInt(str);    // 123
double d = Double.parseDouble("3.14"); // 3.14

特殊类型转换

  • char与int的转换:
    char可以自动转换为int(ASCII值):

    java 复制代码
    char c = 'A';
    int ascii = c;  // 65
  • int强制转为char:

    java 复制代码
    int code = 97;
    char ch = (char) code;  // 'a'

注意

  1. 不能对布尔值进行转换
  2. 不能把对象类型转换为不相干的类型
  3. 把高容量转化到低容量的时候,是强制转换
  4. 转换的时候可能存在内存溢出,或者精度问题

变量

Java变量是存储数据的基本单元,需先声明后使用。声明语法为:数据类型 变量名 = 值;

java 复制代码
// 声明单个变量并赋值
int age = 20;

// 声明多个同类型变量,部分赋值
double height, weight = 65.5;

// 声明多个同类型变量并全部赋值
String name = "Alice", gender = "female";

变量的命名规则

  1. 以字母、_或$开头,不能以数字开头。
  2. 区分大小写,不能使用Java关键字(如class、public)。
  3. 推荐使用驼峰命名法(如studentName)。

变量的初始化

变量声明后可赋值,也可直接初始化:

java 复制代码
int count = 10;  
double price = 19.99;  
boolean isActive = true;  

变量的作用域

局部变量:在方法或代码块内声明,仅在其范围内有效。

成员变量:在类中声明,整个类中可用(实例变量或静态变量)。

常量

在Java中,常量是指一旦赋值后不能被修改的变量。通常使用final关键字声明,表示其值不可变。常量可以是基本数据类型(如int、double)或对象引用(如String)。

  • 基本数据类型常量
java 复制代码
final int MAX_VALUE = 100;
final double PI = 3.14159;
  • 对象引用常量
java 复制代码
final String MESSAGE = "Hello, World!";
  • 静态常量(类常量)
    结合static和final,通常用于全局常量:
java 复制代码
public static final String DEFAULT_NAME = "Unknown";

注:final修饰的引用类型常量仅保证引用不变,对象内容可能可变(如final List仍可添加元素)。 编译时常量(如final int X = 10)会直接内联到代码中,运行时不会重复计算。 类常量通过类名直接访问,如ClassName.DEFAULT_NAME。

常量的命名规范

  • 使用全大写字母,单词间用下划线分隔(如MAX_SIZE)。
  • 名称应清晰表达其用途,避免魔法数字(如直接使用3.14)。

运算符

Java中的运算符用于执行各种操作,如算术运算、逻辑运算、赋值等。运算符可以分为以下几类:

算术运算符

+:加法

-:减法

*:乘法

/:除法

%:取模(取余)

++:自增(前缀或后缀)

--:自减(前缀或后缀)

关系运算符

==:等于

!=:不等于
>:大于

<:小于
>=:大于等于
<=:小于等于

逻辑运算符

&&:逻辑与 ---> 结果都为真---> 一假为假

java 复制代码
(b&&a) // 如果b为假 ,后面就短路了,不会执行

||:逻辑或 ---> 一真为真 ---> 都假为假

!:逻辑非 ---> 真变假 ---> 假变真

位运算符

&:按位与

|:按位或

^:按位异或

~:按位取反

<<:左移
>>:右移(带符号)
>>>:无符号右移

java 复制代码
int num1 = 5; // 二进制 0101
int num2 = 3; // 二进制 0011
System.out.println(num1 & num2); // 输出1 (0001)
System.out.println(num1 << 1); // 输出10 (1010)

赋值运算符

=:简单赋值

+=:加后赋值

-=:减后赋值

*=:乘后赋值

/=:除后赋值

%=:取模后赋值

<<=:左移后赋值
>>=:右移后赋值

&=:按位与后赋值

|=:按位或后赋值

^=:按位异或后赋值

条件运算符(三元运算符)

语法:条件 ? 表达式1 : 表达式2

如果条件为真,返回表达式1的值,否则返回表达式2的值。

instanceof运算符

用于检查对象是否是特定类的实例或其子类的实例。

java 复制代码
String str = "Hello";
System.out.println(str instanceof String); // 输出true

优先级

运算符的优先级决定了表达式中运算的顺序。以下是从高到低的优先级:

  1. ()、[]、.(括号、数组下标、成员访问)
  2. !、~、++、--(逻辑非、位非、自增、自减)
  3. *、/、%(乘、除、取模)
  4. +、-(加、减)
  5. <<、>>、>>>(移位)
  6. <、<=、>、>=、instanceof(关系运算)
  7. ==、!=(相等性)
  8. &(按位与)
  9. ^(按位异或)
  10. |(按位或)
  11. &&(逻辑与)
  12. ||(逻辑或)
  13. ?:(条件运算符)
  14. =、+=、-=等(赋值)

包机制

Java 包(Package)是一种用于组织类和接口的命名空间机制,主要解决类名冲突问题,同时便于模块化管理代码。包通过目录结构实现物理存储,并通过 package 和 import 关键字在代码中声明和使用。

作用

  1. 避免命名冲突:不同包中允许存在同名类。
  2. 访问控制:通过 protected、default(包私有)等修饰符实现包内可见性。
  3. 模块化组织:将功能相关的类归类到同一包中,如 java.util、java.io

包的定义与使用

  1. 声明包
    在 Java 文件首行通过 package 关键字声明所属包,包名通常采用逆域名规范(如 com.example.util):
java 复制代码
package com.example.util;  
public class StringUtils { ... }
  1. 导入包
    通过 import 引入其他包的类或静态成员
java 复制代码
import java.util.List;          // 导入单个类  
import java.util.*;             // 导入包内所有类(不推荐,可能冲突)  
import static java.lang.Math.PI; // 导入静态成员  
  1. 包的目录结构
    包名与文件系统的目录结构需严格对应
  • 包 com.example.util → 文件路径为 ./com/example/util/StringUtils.java
  • 编译后的 .class 文件也需放在相同目录下。

JavaDoc

JavaDoc 是 Java 提供的文档生成工具,用于从源代码中的注释生成 HTML 格式的 API 文档。通过标准化注释语法,开发者可以直接在代码中编写文档,并通过工具自动生成可读性强的文档页面。

JavaDoc 注释语法

JavaDoc 注释以 /** 开头,以 */ 结尾,中间包含描述和标签(Tags)。
示例:

java 复制代码
/**
 * 方法的简要描述。
 * 
 * <p>详细描述或其他说明(可跨多行)。</p>
 * 
 * @param 参数名 参数说明
 * @return 返回值说明
 * @throws 异常类型 异常说明
 */
public int exampleMethod(String param) throws Exception {
    // 方法实现
}

常用 JavaDoc 标签

  • @param:描述方法参数。
  • @return:描述返回值。
  • @throws / @exception:描述可能抛出的异常。
  • @see:添加相关参考链接(类、方法或URL)。
  • @deprecated:标记已过时的代码。
  • @since:说明从哪个版本开始引入。
  • @author:标注作者(通常用于类注释)。
  • @version:标注版本号。

生成 JavaDoc 文档

通过命令行或 IDE 工具生成文档:

命令行方式(示例):

bash 复制代码
javadoc -d doc_directory -sourcepath src_path -subpackages com.example
  • -d:指定输出目录。
  • -sourcepath:指定源代码路径。
  • -subpackages:递归处理子包。

IDE 支持:

  • IntelliJ IDEA :通过菜单栏的 Tools > Generate JavaDoc 生成。
  • Eclipse :右键项目 > Export > JavaDoc

注释规范建议

  1. 类注释 :放在类定义前,包含类功能、作者和版本信息。

    java 复制代码
    /**
     * 提供用户管理的核心功能。
     * 
     * @author John Doe
     * @version 1.0
     */
    public class UserManager { ... }
  2. 方法注释:清晰描述方法作用、参数、返回值和异常。

  3. 字段注释:对公共字段或复杂逻辑字段进行说明。

高级功能

  • HTML 标签 :在注释中使用 <p><code> 等标签增强格式。
  • {@link}:内联链接到其他类或方法,例如 {@link String#equals}
  • {@code}:以代码字体显示内容,例如 {@code int x = 0;}

注意事项

  • 避免冗余注释,仅对公共 API 或关键逻辑添加文档。
  • 生成的文档需定期维护,确保与代码同步。
  • 可通过 -encoding UTF-8 参数指定编码(避免中文乱码)。

Java 控制流程

用户交互Scanner

java.util.Scanner 是 Java 核心类库中用于从不同输入源读取基本数据类型(int/long/float 等)和字符串的工具类,无需手动处理输入流的底层操作,是日常开发、算法题中处理控制台输入的首选,使用前需先导入该类。

导入包

Scanner 位于 java.util 包下,非 java.lang 核心包(该包无需手动导入),因此所有使用 Scanner 的代码,必须在文件顶部添加导入语句
java import java.util.Scanner;

使用流程(3步)

使用 Scanner 处理控制台输入的固定流程,直接复用即可,核心是「创建对象→读取数据→关闭资源」:

  1. 创建Scanner对象(绑定控制台输入源)

    控制台输入的标准源是 System.in,创建对象时将其传入,完成 Scanner 与控制台输入的绑定:

    java 复制代码
    Scanner sc = new Scanner(System.in); // 核心:绑定System.in,接收控制台输入
  2. 读取输入数据(按类型选择方法)

    Scanner 提供了针对不同基本数据类型的专用读取方法,直接调用即可获取对应类型的输入,无需手动类型转换,常用方法如下:

    读取方法 对应数据类型 说明
    nextInt() int 读取整数
    nextLong() long 读取长整数
    nextFloat() float 读取单精度浮点数
    nextDouble() double 读取双精度浮点数(常用)
    next() String 读取非空格分隔的字符串(遇到空格 / 回车停止)
    nextLine() String 读取整行字符串(包含空格,直到回车停止,最常用)
    1. 关闭Scanner对象(释放资源)
      Scanner 绑定了 System.in 输入流,属于需要手动释放的资源,使用完毕后必须调用 close() 方法关闭,否则会造成资源泄漏:
java 复制代码
sc.close(); // 核心:使用结束后关闭,放在代码最后执行

next()与nextLine()坑点

  • next() 方法
    核心特点:以有效字符为起点,以空白(空格、Tab、换行等)为分隔符或结束符。
    行为逻辑:
    会自动跳过输入有效字符前的所有空白,直到读取到第一个有效字符。
    读取到有效字符后,遇到下一个空白就停止,不会包含这个空白。
    必须读取到有效字符才会结束输入,无法得到带有空格的字符串。
    典型场景:适合读取单个不含空格的单词或数据,如用户名、数字等。
  • nextLine() 方法(常用)
    核心特点:以回车键(Enter)为结束符,会读取回车之前的所有字符。
    行为逻辑:
    可以读取包含空格、Tab 在内的所有字符,直到用户按下回车键。
    会将回车键本身作为结束标记,但不会包含在返回的字符串中。
    典型场景:适合读取一整行文本,如用户输入的地址、完整句子等。
  • 常见坑点与解决
    在实际开发中,如果先调用 next() 再调用 nextLine(),容易出现 nextLine() 直接读取到空字符串的问题,这是因为 next() 会留下回车键在输入缓冲区中,nextLine() 会直接读取这个回车键并结束。
  • 解决方法:
    在 next() 之后,额外调用一次 nextLine() 来清空缓冲区中的回车键。
    或者全程使用 nextLine(),再对读取的内容进行分割或转换。

Java 的三大基本程序结构

顺序结构

a顺序结构是三大基本程序结构(顺序、选择、循环)中最基础的一种,核心规则是程序代码按照从上到下、从左到右的书写顺序依次执行,无跳转、无分支、无重复,每一行代码执行完毕后,才会执行下一行,流程清晰且唯一,是所有 Java 程序的基础(任何复杂程序的核心片段,底层都是顺序结构的组合)。
特点

  • 顺序执行:代码执行顺序与书写顺序完全一致,无任何逻辑判断或循环干预;
  • 无分支无重复:不会跳过某段代码,也不会重复执行某段代码;
  • 基础结构:选择结构(if/switch)、循环结构(for/while/do-while)都是在顺序结构基础上扩展而来。

选择结构

选择结构是三大基本程序结构(顺序、选择、循环) 之一,核心是根据指定条件的布尔结果(true/false),决定程序的执行分支,会跳过不满足条件的代码块,打破顺序结构的 "单向执行" 特性,是实现程序逻辑判断的核心结构。

Java 提供两种核心选择结构:if 系列选择结构(支持单分支、多分支、嵌套,灵活处理复杂条件)、switch 选择结构(支持多值匹配,代码简洁,适合固定值的分支判断)
equals 比较字符串是否相等

if 选择结构语法
  • 单分支 if 结构(满足条件才执行)

    java 复制代码
    if (布尔表达式) {
        // 布尔表达式为 true 时,执行的代码块
    }
    // 表达式为 false 时,直接跳过代码块,执行后续代码
    
    //示范
    public class IfDemo {
    public static void main(String[] args) {
        int score = 85;
        // 单分支:分数≥80时,打印表扬信息
        if (score >= 80) {
            System.out.println("成绩优秀,继续加油!");
        }
        System.out.println("程序执行结束"); // 无论条件是否成					立,都会执行
    }
    }
  • 双分支 if-else 结构(二选一执行)

    java 复制代码
    if (布尔表达式) {
        // 布尔表达式为 true 时,执行的代码块1
    } else {
        // 布尔表达式为 false 时,执行的代码块2
    }
    // 示例
    public class IfElseDemo {
    public static void main(String[] args) {
        int score = 55;
        // 双分支:分数≥60及格,否则不及格
        if (score >= 60) {
            System.out.println("成绩及格,顺利通过!");
        } else {
            System.out.println("成绩不及格,需要补考!");
       	 }
      }
    }
  • 多分支 if-else if-else 结构(多选一执行)

    有多个互斥执行分支,程序从上到下依次判断布尔表达式,只要有一个条件成立,执行对应代码块后直接跳出整个 if 结构;后续的 else if 分支不再判断,实现 "多选一" 效果;最后的 else 为默认分支(可选),当所有条件都不成立时执行,若省略 else,所有条件不成立则直接跳过整个结构。

    java 复制代码
    if (布尔表达式1) {
        // 表达式1为 true 时,执行代码块1
    } else if (布尔表达式2) {
        // 表达式1为 false、表达式2为 true 时,执行代码块2
    } else if (布尔表达式3) {
        // 表达式1、2为 false、表达式3为 true 时,执行代码块3
    }
    // 可添加任意多个 else if 分支
    else {
        // 所有表达式都为 false 时,执行默认代码块(可选)
    }
    
    //示例
    public class IfElseIfDemo {
        public static void main(String[] args) {
            int score = 75;
            String grade;
            // 多分支:根据分数划分等级
            if (score >= 90) {
                grade = "A(优秀)";
            } else if (score >= 80) {
                grade = "B(良好)";
            } else if (score >= 70) {
                grade = "C(中等)";
            } else if (score >= 60) {
                grade = "D(及格)";
            } else {
                grade = "E(不及格)";
            }
            System.out.println("你的成绩等级为:" + grade);
        }
    }
  • if 结构的嵌套

    在一个 if/else 代码块中,嵌套另一个 if 系列结构,用于处理多层级的条件判断(如 "先判断是否及格,及格后再判断是否优秀")。

java 复制代码
public class IfNestDemo {
    public static void main(String[] args) {
        int score = 95;
        if (score >= 60) {
            System.out.println("成绩及格");
            // 嵌套单分支:及格的前提下,判断是否为优秀
            if (score >= 90) {
                System.out.println("且成绩优秀,获得奖学金!");
            }
        } else {
            System.out.println("成绩不及格,需要补考");
        }
    }
}
switch 选择结构语法

switch 结构是多值匹配的选择结构,核心是将一个表达式的结果与多个常量值逐一匹配,匹配成功则执行对应分支的代码,适合处理 "固定值判断" 的场景(如按月份判断季节、按数字判断星期),代码比多分支 if-else if 更简洁。

  • 基础语法
java 复制代码
switch (表达式) {
    case 常量值1:
        // 表达式结果 == 常量值1 时,执行的代码块
        break; // 跳出整个 switch 结构(可选,关键)
    case 常量值2:
        // 表达式结果 == 常量值2 时,执行的代码块
        break;
    // 可添加任意多个 case 分支
    default:
        // 表达式结果与所有常量值都不匹配时,执行的默认代码块(可选)
        break;
}
注意
  1. 表达式支持的类型:JDK 7 及以上支持 byte/short/int/char 及其包装类、String 字符串、enum 枚举;不支持 long、double、float 等类型;
  2. case 常量要求:case 后必须是常量值(字面量、final 常量)不能是变量、表达式(如 case 1+2 合法,case a 不合法);且多个 case 的常量值不能重复
  3. break 关键字的作用:执行完某个 case 的代码后,通过 break 跳出整个 switch 结构,避免执行后续 case 代码(即 "穿透现象");
  4. default 分支:可选,位置可任意(建议放在最后),当所有 case 都不匹配时执行,若省略则直接跳过 switch 结构;
  5. 穿透现象:如果 case 分支后没有 break,程序会从匹配成功的 case 开始,依次执行后续所有 case 的代码(包括 default),直到遇到 break 或 switch 结束(可利用穿透实现多值共用一个代码块)。
穿透现象的利用(多值共用代码块)

适用于 "多个常量值对应同一逻辑" 的场景,如按月份判断季节(3/4/5 月为春季),无需重复编写代码。

java 复制代码
public class SwitchPenetrateDemo {
    public static void main(String[] args) {
        int month = 4;
        switch (month) {
            case 3:
            case 4:
            case 5:
                System.out.println(month + "月,春季");
                break; // 匹配3/4/5任意一个,执行后跳出
            case 6:
            case 7:
            case 8:
                System.out.println(month + "月,夏季");
                break;
            case 9:
            case 10:
            case 11:
                System.out.println(month + "月,秋季");
                break;
            case 12:
            case 1:
            case 2:
                System.out.println(month + "月,冬季");
                break;
            default:
                System.out.println("无效的月份");
        }
    }
}
JDK 14 新特性:switch 表达式(简化写法)

JDK 14 引入switch 表达式(可直接赋值给变量),替代传统 switch 语句,自动避免穿透,代码更简洁,支持 -> 语法和 yield 返回值

java 复制代码
public class SwitchExpressionDemo {
    public static void main(String[] args) {
        int month = 10;
        // switch 表达式直接赋值给变量,无需break,自动避免穿透
        String season = switch (month) {
            case 3,4,5 -> "春季"; // 多值用逗号分隔,-> 后跟结果
            case 6,7,8 -> "夏季";
            case 9,10,11 -> "秋季";
            case 12,1,2 -> "冬季";
            default -> "无效月份";
        };
        System.out.println(month + "月," + season);
    }
}

选型核心原则

  • 用 if:当需要判断范围(如 score >= 90)、多条件组合(如 age > 18 && score >= 60)时,if 结构是唯一选择;
  • 用 switch:当需要对固定值做等值匹配(如按星期、月份、枚举值分支)时,优先用 switch,代码更简洁易维护;
  • 简单多值匹配(如 3-5 个值):if 和 switch 均可,根据个人习惯选择;
  • 大量多值匹配(如 10 个以上):优先用 switch,执行效率略高于 if-else if(JVM 会对 switch 做优化)。

循环结构

循环结构是三大基本程序结构(顺序、选择、循环) 的核心组成,核心作用是根据指定条件,重复执行某一段代码块(循环体),避免重复编写相同逻辑,大幅简化代码、提升开发效率。当条件不满足时,循环终止,程序继续执行后续代码。

Java 提供三种核心循环结构(for/while/do-while),还有增强 for 循环(for-each) 专为遍历集合 / 数组设计,同时支持 break/continue 关键字控制循环流程,以下分模块详细讲解,包含语法、特点、示例及选型建议。

while 循环结构

while 循环是最基础的条件循环,核心逻辑是先判断条件,再执行循环体,适合循环次数不确定的场景(仅知道终止条件,不知道要执行多少次)。

java 复制代码
// 1. 初始化循环变量(可选,可在外部定义)
初始化语句;
while (布尔条件表达式) {
    // 2. 循环体:条件为true时,重复执行的代码
    循环体语句;
    // 3. 循环变量更新(必须写,否则会造成死循环)
    变量更新语句;
}
// 条件为false时,跳出循环,执行后续代码

// 示例:
public class WhileDemo {
    public static void main(String[] args) {
        int i = 1; // 初始化循环变量:从1开始
        int sum = 0; // 初始化总和变量
        // 条件:i≤10时,继续循环
        while (i <= 10) {
            sum += i; // 循环体:累加当前i到sum
            i++; // 变量更新:i自增1(关键,避免死循环)
        }
        System.out.println("1~10的累加和:" + sum); // 循环结束后使用i和sum
        System.out.println("循环结束后i的值:" + i);
    }
}

注:

  1. 「先判断,后执行」:如果初始条件直接为 false,循环体一次都不会执行;
  2. 必须包含「循环变量更新语句」:否则循环条件永远为 true,造成死循环(程序无限执行,无法终止);
  3. 循环变量通常在外部定义:方便循环结束后继续使用该变量。

do...while 循环结构

do-while 循环是 while 循环的变体,核心逻辑是先执行一次循环体,再判断条件,适合循环体至少需要执行一次的场景(如用户输入验证,必须先让用户输入,再判断是否合法)。

java 复制代码
// 1. 初始化循环变量
初始化语句;
do {
    // 2. 循环体:先执行一次,再判断条件
    循环体语句;
    // 3. 循环变量更新
    变量更新语句;
} while (布尔条件表达式); // 注意:末尾必须加分号


// 示例
import java.util.Scanner;

public class DoWhileDemo {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int num = 0;
        boolean isLegal = false;
        // 至少执行一次:先让用户输入,再判断是否合法
        do {
            System.out.print("请输入一个1~100的整数:");
            if (sc.hasNextInt()) { // 判断是否为整数
                num = sc.nextInt();
                if (num >= 1 && num <= 100) {
                    isLegal = true; // 输入合法,标记为true
                } else {
                    System.out.println("数字超出范围,请重新输入!");
                }
            } else {
                System.out.println("输入不是整数,请重新输入!");
                sc.next(); // 清空无效输入,避免死循环
            }
        } while (!isLegal); // 输入不合法时,继续循环
        
        System.out.println("输入成功!你输入的数字是:" + num);
        sc.close();
    }
}

注:

  1. 「先执行,后判断」:无论初始条件是否为 true,循环体都会执行至少一次(这是与while循环的核心区别);
  2. 末尾必须加分号:容易遗漏,是常见语法错误;
  3. 同样需要变量更新语句,避免死循环。

for 循环结构

for 循环是最常用、最规范的循环结构,将「初始化、条件判断、变量更新」三个核心步骤集中在一行,代码简洁、结构清晰,适合循环次数确定的场景(如遍历数组、固定次数的累加 / 遍历)。

  1. 三要素集中管理:初始化、条件、更新在一行,易读易维护,减少死循环概率;
  2. 循环变量作用域:若在初始化中定义(如for(int i=0;...)),则仅在循环体内有效,循环结束后无法使用(可避免变量污染);
  3. 灵活性高:三要素均可省略(但分号不能省),可实现无限循环或适配复杂场景。
java 复制代码
for (①初始化表达式; ②布尔条件表达式; ④变量更新表达式) {
    // ③循环体:条件为true时执行
    循环体语句;
}
// 条件为false时,跳出循环,执行后续代码

// 示例
public class ForDemo {
    public static void main(String[] args) {
        // 初始化:i=1;条件:i≤5;更新:i++
        for (int i = 1; i <= 5; i++) {
            System.out.println("当前i的值:" + i);
        }
        // 报错:i在此处未定义(作用域仅在循环内)
        // System.out.println(i);
    }
}
变体:无限循环(for循环省略三要素)
java 复制代码
// 分号不能省略,条件表达式省略默认为true,造成无限循环
for (;;) {
    System.out.println("无限循环中...");
    // 需配合break关键字终止循环,否则程序卡死
    if (某条件) {
        break;
    }
}

增强 for 循环(for-each)

专用于遍历集合 / 数组

增强 for 循环是 JDK 5 引入的简化遍历语法,底层基于迭代器实现,无需关心循环次数和索引,直接遍历集合 / 数组中的每一个元素,适合仅读取元素、不修改元素的遍历场景(如打印数组所有元素、求和)。

java 复制代码
// 遍历数组
for (元素数据类型 变量名 : 数组名) {
    // 变量名 = 数组中当前遍历的元素,直接使用即可
}

// 遍历集合(如ArrayList/LinkedList)
for (元素数据类型 变量名 : 集合名) {
    // 变量名 = 集合中当前遍历的元素
}


// 示例
// 遍历数组(求和 + 打印)
public class ForEachArrayDemo {
    public static void main(String[] args) {
        int[] nums = {10, 20, 30, 40, 50};
        int sum = 0;
        // 遍历数组:num依次代表数组中的每个元素
        for (int num : nums) {
            sum += num;
            System.out.println("数组元素:" + num);
        }
        System.out.println("数组元素总和:" + sum);
    }
}


// 遍历集合(ArrayList)
import java.util.ArrayList;
import java.util.List;

public class ForEachCollectionDemo {
    public static void main(String[] args) {
        List<String> names = new ArrayList<>();
        names.add("张三");
        names.add("李四");
        names.add("王五");
        // 遍历集合:name依次代表集合中的每个字符串
        for (String name : names) {
            System.out.println("姓名:" + name);
        }
    }
}
  • 无索引、无循环变量:无需手动控制索引,避免索引越界异常(数组遍历的常见错误);
  • 只读不可改:遍历的是元素的副本,修改遍历变量不会改变原数组 / 集合的元素;
  • 遍历顺序:数组 / 有序集合(如 ArrayList)按正序遍历,无序集合(如 HashSet)按底层存储顺序遍历;
  • 适用范围:仅支持实现了 Iterable 接口的对象(数组、Collection 系列集合),不支持 Map(可通过map.keySet()/map.values()间接遍历)。

循环控制关键字 break & continue

Java 提供 breakcontinue 两个关键字,用于灵活控制循环的执行流程,打破 "从头走到尾" 的默认循环规则,适配复杂的循环逻辑(如提前终止循环、跳过某次循环)。

break 关键字:强制终止循环

核心作用

  1. 执行到 break 时,立即跳出当前所在的循环(for/while/do-while),循环直接结束,后续循环体和变量更新都不再执行;
  2. 支持嵌套循环:仅跳出最近的一层循环(外层循环继续执行);
  3. 也可用于 switch 结构(之前选择结构中讲解过)。
java 复制代码
// 示例:找到 1~10 中第一个能被 3 整除的数,找到后立即终止循环
public class BreakDemo {
    public static void main(String[] args) {
        for (int i = 1; i <= 10; i++) {
            if (i % 3 == 0) {
                System.out.println("找到第一个能被3整除的数:" + i);
                break; // 立即终止循环,后续i=4~10不再遍历
            }
            System.out.println("当前遍历:" + i);
        }
        System.out.println("循环结束");
    }
}

continue 关键字:跳过本次循环,继续下一次

核心作用

  1. 执行到 continue 时,跳过当前次循环的剩余代码,直接执行变量更新语句,然后回到条件判断,继续下一次循环;
  2. 仅跳过本次,循环不会终止,后续满足条件仍会执行;
  3. 同样仅作用于最近的一层循环。
java 复制代码
// 示例:打印 1~10 中的奇数,跳过偶数
public class ContinueDemo {
    public static void main(String[] args) {
        for (int i = 1; i <= 10; i++) {
            if (i % 2 == 0) {
                continue; // 跳过偶数,直接执行i++,进入下一次循环
            }
            System.out.println("奇数:" + i); // 仅奇数会执行此行
        }
    }
}

break & continue 核心区别对比

关键字 核心作用 循环状态 后续执行逻辑
break 强制终止循环 直接结束 跳出循环,执行循环外的代码
continue 跳过本次循环的剩余代码 继续执行 执行变量更新,回到条件判断

嵌套循环:循环中包含循环

嵌套循环是指在一个循环的循环体中,再定义另一个循环,外层循环控制 "行",内层循环控制 "列",适合实现二维结构的遍历 / 打印(如九九乘法表、矩形、三角形)。

外层循环执行一次,内层循环会完整执行所有次数;

支持多层嵌套(但不建议超过 3 层,否则代码可读性极差);

break/continue 仅作用于所在的那一层循环,不会影响外层循环。

java 复制代码
// 示例
public class NestedForDemo {
    public static void main(String[] args) {
        // 外层循环:控制行数(1~9行)
        for (int i = 1; i <= 9; i++) {
            // 内层循环:控制列数(1~当前行数i)
            for (int j = 1; j <= i; j++) {
                System.out.print(j + "×" + i + "=" + (i*j) + "\t");
            }
            System.out.println(); // 每行结束后换行
        }
    }
}

Java 的方法

Java 方法(Method)是将一段完成特定功能的代码块进行封装的语法结构,能实现代码复用、简化逻辑、提升可维护性,是 Java 编程的核心基础之一。简单来说,方法就是一段可被多次调用的 "功能函数",定义一次即可在任意位置重复执行,避免重复编写相同代码。

方法的核心价值:封装逻辑、复用代码、解耦功能、便于调试和维护,一个完整的 Java 程序就是由多个方法(如main方法、自定义方法)组合而成的。

方法的基本概念与结构

Java 方法由方法声明(方法头)方法体两部分组成,声明定义方法的 "标识和规则",体实现具体功能,语法结构固定且规范:

java 复制代码
【修饰符】 返回值类型 方法名(【参数列表】) {
    // 方法体:完成具体功能的代码块
    执行语句;
    【return 返回值;】 // 有返回值时必须写,无返回值时可省略return(或仅写return;)
}

设计方法原则:方法本意是功能块,实现某个功能的语句块的集合。我们设计方法的时候,最好保持方法的原子性,就是一个方法只完成1个功能,有利于后期的扩展。

组成部分 说明
修饰符 可选,如 public/private/static/final 等,控制方法的访问权限和特性
返回值类型 方法执行后返回的数据类型:无返回值用 void;有返回值需指定具体类型(如 int/String)
方法名 符合标识符命名规范,小驼峰式(如 addNum),见名知意
参数列表 可选,格式:数据类型 参数名[, 数据类型 参数名...],是方法接收的输入数据
方法体 方法的核心逻辑代码块
return 可选:无返回值(void):可省略 return,或写 return; 终止方法;有返回值:必须通过 return 返回对应类型的值

方法的调用

Java都是值传递

概念 说明
静态方法 用 static 修饰,属于「类」本身,不依赖对象即可调用(如 main 方法)
实例方法 无 static 修饰,属于「对象」,必须创建对象后才能调用
形参 方法定义时的参数(如 add(int a) 中的 a),是 "输入占位符"
实参 方法调用时传入的具体值(如 add(5) 中的 5),需与形参匹配
静态方法调用
  • 同类中调用直接使用[ 方法名(实参)]

    java 复制代码
    // 示例
    package com.day1;
    
    public class StaticMethodDemo {
        // 定义静态方法:加法
        public static int add(int a, int b) {
            return a + b;
        }
    
        // 主方法(静态):程序入口
        public static void main(String[] args) {
            // 同类中调用静态方法:直接调用
            int result = add(10, 20); 
            System.out.println(result); // 输出 30
        }
    }
  • 不同类中调用静态方法

    格式:类名.方法名(实参)(需保证方法访问权限为 public/protected 或同包默认)。

    java 复制代码
    // 步骤 1:定义被调用的类(含静态方法)
    // 包名:com.utils
    package com.utils;
    
    public class MathUtil {
        // 公共静态方法:计算两数乘积
        public static int multiply(int a, int b) {
            return a * b;
        }
    }
    
    // 步骤 2:在另一个类中调用
    // 包名:com.day1(与MathUtil不同包)
    package com.day1;
    
    // 导入目标类(不同包必须导入,同包可省略)
    import com.utils.MathUtil;
    
    public class TestCall {
        public static void main(String[] args) {
            // 不同类调用静态方法:类名.方法名
            int product = MathUtil.multiply(5, 6);
            System.out.println(product); // 输出 30
        }
    }
实例方法调用

实例方法依赖对象存在,必须先创建对象,再通过「对象。方法名」调用。

  • 同类中调用实例方法
java 复制代码
package com.day1;

public class InstanceMethodDemo {
    // 定义实例方法:无static修饰
    public String sayHello(String name) {
        return "你好," + name + "!";
    }

    public static void main(String[] args) {
        // 步骤1:创建当前类的对象(关键字new)
        InstanceMethodDemo demo = new InstanceMethodDemo();
        
        // 步骤2:通过对象调用实例方法
        String hello = demo.sayHello("Java");
        System.out.println(hello); // 输出:你好,Java!
    }
}

方法的重载(Overload)

方法重载是 Java 中实现 "同名不同逻辑" 的核心特性,也是面向对象编程中多态的基础体现之一。以下从定义、规则、示例、应用场景到避坑点,全方位讲解方法重载。

  • 核心价值:简化同名功能的方法调用(比如 add 方法既可以加 int,也可以加 double,不用命名为 addInt/addDouble);
  • 关键误区:方法重载与返回值类型、修饰符无关,仅看「参数列表」

|须满足的核心条件(缺一不可)

条件 说明
同一类中 重载方法必须在同一个类内(子类与父类的同名方法是重写,不是重载)
方法名完全相同 比如都叫 add、都叫 print
参数列表必须不同 满足以下任一即可:① 参数个数不同(如 add(int a) vs add(int a, int b));② 参数类型不同(如 add(int a) vs add(double a));③ 参数顺序不同(如 add(int a, double b) vs add(double a, int b))。
java 复制代码
// 示例

// 参数个数不同的重载
public class OverloadDemo1 {
    // 重载1:两个int相加
    public static int add(int a, int b) {
        return a + b;
    }

    // 重载2:三个int相加(参数个数不同)
    public static int add(int a, int b, int c) {
        return a + b + c;
    }

    public static void main(String[] args) {
        System.out.println(add(1, 2));    // 调用重载1,输出3
        System.out.println(add(1, 2, 3)); // 调用重载2,输出6
    }
}



// 参数类型不同的重载
public class OverloadDemo2 {
    // 重载1:int类型加法
    public static int add(int a, int b) {
        return a + b;
    }

    // 重载2:double类型加法(参数类型不同)
    public static double add(double a, double b) {
        return a + b;
    }

    public static void main(String[] args) {
        System.out.println(add(1, 2));      // 调用重载1,输出3
        System.out.println(add(1.5, 2.5));  // 调用重载2,输出4.0
    }
}

// 参数顺序不同的重载(极少用,但合法)
public class OverloadDemo3 {
    // 重载1:int在前,double在后
    public static double calculate(int a, double b) {
        return a + b;
    }

    // 重载2:double在前,int在后(参数顺序不同)
    public static double calculate(double a, int b) {
        return a * b;
    }

    public static void main(String[] args) {
        System.out.println(calculate(2, 3.0));  // 调用重载1,输出5.0
        System.out.println(calculate(2.0, 3));  // 调用重载2,输出6.0
    }
}

可变参数

可变参数(Variable Arguments,简称 Varargs)是 JDK 5 引入的特性,允许方法接收任意个数的同类型参数,本质是编译器自动将可变参数封装为数组,简化了多参数方法的定义和调用。

语法:

java 复制代码
[修饰符] 返回值类型 方法名(数据类型... 参数名) {
    // 方法体(参数名可当作数组使用)
}

关键标识:...(三个点)必须紧跟在数据类型后,参数名前;
可变参数必须是方法的最后一个参数(避免参数匹配歧义);
一个方法只能有一个可变参数。

// 示例
public class VarargsDemo {
    // 可变参数方法:计算多个int的和
    public static int sum(int... nums) {
        int total = 0;
        // 可变参数可当作数组遍历
        for (int num : nums) {
            total += num;
        }
        return total;
    }

    public static void main(String[] args) {
        // 调用:可传0个、1个、多个参数
        System.out.println(sum());          // 0(无参数)
        System.out.println(sum(1));         // 1(1个参数)
        System.out.println(sum(1, 2, 3));   // 6(多个参数)
        // 也可直接传数组(编译器自动兼容)
        int[] arr = {4, 5, 6};
        System.out.println(sum(arr));       // 15
    }
}

递归

递归是编程中一种重要的算法思想,指方法自身调用自身,通过将复杂问题拆解为规模更小的同类子问题,最终通过终止条件结束递归并回溯结果。Java 中递归广泛应用于分治算法(如快速排序、归并排序)、树形结构遍历(如二叉树)等场景。

递归的核心要素

|递归必须满足| 两个核心条件,否则会导致栈溢出(StackOverflowError):

要素 说明
递归终止条件 定义 "最小子问题" 的解,当满足条件时停止递归,返回基础值(避免无限递归)
递归递推关系 将原问题拆解为规模更小的子问题,调用自身解决子问题,并逐步向终止条件靠近
java 复制代码
[修饰符] 返回值类型 方法名(参数) {
    // 1. 递归终止条件(必须有)
    if (终止条件) {
        return 基础值;
    }
    // 2. 递推:拆解问题,调用自身
    return 方法名(更小的参数) + 逻辑处理;
}

//二、递归的基础示例
示例 1:计算阶乘(最经典)
阶乘定义:n! = n × (n-1) × (n-2) × ... × 1,且 0! = 1、1! = 1
public class FactorialDemo {
    // 递归计算阶乘
    public static int factorial(int n) {
        // 终止条件:n≤1时返回1
        if (n <= 1) {
            return 1;
        }
        // 递推:n! = n × (n-1)!
        return n * factorial(n - 1);
    }

    public static void main(String[] args) {
        System.out.println(factorial(5)); // 输出:120(5×4×3×2×1)
        System.out.println(factorial(0)); // 输出:1(符合定义)
    }
}

// 过程拆解
factorial(5) → 5 × factorial(4)
factorial(4) → 4 × factorial(3)
factorial(3) → 3 × factorial(2)
factorial(2) → 2 × factorial(1)
factorial(1) → 1(终止条件)
回溯计算:2×1=2 → 3×2=6 → 4×6=24 → 5×24=120

·

相关推荐
嗯嗯**2 小时前
Neo4j学习4:数据导入
学习·neo4j·图数据库·csv·数据导入
鹏哥哥啊Aaaa2 小时前
15.idea启动报错
java·ide·intellij-idea
super_lzb2 小时前
VUE 请求代理地址localhost报错[HPM] Error occurred while trying to proxy request
java·spring·vue·springboot·vue报错
代码游侠2 小时前
学习笔记——Linux内核与嵌入式开发2
linux·运维·arm开发·嵌入式硬件·学习·架构
我是黄骨鱼2 小时前
【零基础学数据库|第四篇】SQL通用语法学习
学习
Dream_sky分享2 小时前
IDEA 2025中TODO找不到
java·ide·intellij-idea
苏渡苇2 小时前
用 Spring Boot 项目给工厂装“遥控器”:一行 API 控制现场设备!
java·人工智能·spring boot·后端·网络协议·边缘计算
伊甸32 小时前
基于LangChain4j从0到1搭建自己的的AI智能体并部署上线-1
java·langchain·prompt
我待_JAVA_如初恋2 小时前
重装系统后,idea被拦截,突然无法运行
java·ide·intellij-idea