---
title: "03-基本语法要点"
aliases:
- "基本语法要点"
created: 2025-12-23
---
# 基本语法要点
---
## 一、注释
### **1.1 三种注释形式**
```java
// ═══════════════════════════════════════════════════════════════════════
// 1. 单行注释:用于解释单行代码逻辑
// ═══════════════════════════════════════════════════════════════════════
int count = 0; // 计数器初始化为0
// ═══════════════════════════════════════════════════════════════════════
// 2. 多行注释:用于解释代码块(实际开发中较少使用)
// ═══════════════════════════════════════════════════════════════════════
/*
* 这是一个多行注释
* 可以跨越多行
* 通常用于临时屏蔽代码块
*/
/* 也可以写成一行 */
// ═══════════════════════════════════════════════════════════════════════
// 3. 文档注释:用于生成 JavaDoc API 文档
// ═══════════════════════════════════════════════════════════════════════
/**
* 计算两个整数的和
*
* @author 张三
* @version 1.0
* @since JDK 1.8
* @param a 第一个加数
* @param b 第二个加数
* @return 两数之和
* @throws ArithmeticException 如果结果溢出
* @see Math#addExact(int, int)
*/
public int add(int a, int b) {
return a + b;
}
```
### **1.2 常用 JavaDoc 标签**
```drawio
```
```
# 生成 JavaDoc 文档
javadoc -d docs -encoding UTF-8 -charset UTF-8 *.java
# 生成的文档结构
docs/
├── index.html # 首页
├── allclasses.html # 所有类列表
├── package-summary.html
└── com/
└── example/
└── MyClass.html
```
### **1.3 注释的本质**
```drawio
```
### **1.4 注释最佳实践**
```java
// ════════════════════════════════════════════════════════════════════════
// ❌ 不好的写法:注释说明显而易见的事情
// ════════════════════════════════════════════════════════════════════════
// 设置 age 为 25
int age = 25;
// 如果 age 大于 18
if (age > 18) {
// 打印成年
System.out.println("成年");
}
// ════════════════════════════════════════════════════════════════════════
// ❌ 不好的写法:注释解释复杂逻辑
// ════════════════════════════════════════════════════════════════════════
// 检查员工是否有资格获得全部福利
// 条件:按小时计费 且 年龄大于65岁
if ((employee.flags & HOURLY_FLAG) && (employee.age > 65)) {
// ...
}
// ════════════════════════════════════════════════════════════════════════
// ✅ 好的写法:用清晰的命名代替注释
// ════════════════════════════════════════════════════════════════════════
if (employee.isEligibleForFullBenefits()) {
// ...
}
// ════════════════════════════════════════════════════════════════════════
// ✅ 好的写法:注释解释 "为什么" 而非 "是什么"
// ════════════════════════════════════════════════════════════════════════
// 使用 insertion sort 而非 quicksort,因为数据量小于 10 且几乎有序
// 参考性能测试结果:benchmark_2024.md
Arrays.sort(smallArray);
// 保留 2 的缓冲空间,避免频繁扩容
// 根据历史数据,99% 的请求不超过 capacity + 2
List- items = new ArrayList<>(capacity + 2);
```
```drawio
```
---
## 二、标识符与关键字
### **2.1 标识符**
```drawio
```
**标识符命名规则**:
```drawio
```
**命名规范(约定俗成)**:
```java
// ═══════════════════════════════════════════════════════════════════════
// 类名、接口名:大驼峰 (UpperCamelCase)
// ═══════════════════════════════════════════════════════════════════════
public class UserService { }
public interface OrderRepository { }
public class IOException extends Exception { }
// ═══════════════════════════════════════════════════════════════════════
// 方法名、变量名:小驼峰 (lowerCamelCase)
// ═══════════════════════════════════════════════════════════════════════
public void getUserById() { }
int itemCount = 0;
String firstName = "John";
// ═══════════════════════════════════════════════════════════════════════
// 常量名:全大写 + 下划线分隔 (SCREAMING_SNAKE_CASE)
// ═══════════════════════════════════════════════════════════════════════
public static final int MAX_RETRY_COUNT = 3;
public static final String DEFAULT_CHARSET = "UTF-8";
public static final double PI = 3.14159265358979;
// ═══════════════════════════════════════════════════════════════════════
// 包名:全小写,用点分隔
// ═══════════════════════════════════════════════════════════════════════
package com.example.project.module;
package org.apache.commons.lang3;
// ═══════════════════════════════════════════════════════════════════════
// 泛型类型参数:单个大写字母
// ═══════════════════════════════════════════════════════════════════════
public class Box { } // T - Type
public class Map { } // K - Key, V - Value
public class List { } // E - Element
public R execute(Supplier supplier) // R - Return
```
### **2.2 关键字**
```drawio
```
**Java 关键字分类一览**:
```drawio
```
**关键字详细说明**:
```java
// ═══════════════════════════════════════════════════════════════════════
// 访问控制关键字
// ═══════════════════════════════════════════════════════════════════════
public class AccessDemo {
public int publicVar; // 公开:任何地方都可访问
protected int protectedVar; // 受保护:同包 + 子类可访问
int defaultVar; // 默认:同包可访问 (无关键字)
private int privateVar; // 私有:仅本类可访问
}
// ═══════════════════════════════════════════════════════════════════════
// 类相关关键字
// ═══════════════════════════════════════════════════════════════════════
abstract class Animal { } // abstract: 抽象类/方法
class Dog extends Animal { } // extends: 继承
interface Runnable { } // interface: 接口
class Cat implements Runnable { } // implements: 实现接口
final class String { } // final: 不可继承/修改
static int count; // static: 静态成员
// ═══════════════════════════════════════════════════════════════════════
// 特殊关键字
// ═══════════════════════════════════════════════════════════════════════
// native: 本地方法,由 C/C++ 实现
public native int hashCode();
// strictfp: 严格浮点计算,保证跨平台结果一致
strictfp class StrictMath { }
// transient: 序列化时忽略该字段
transient int tempData;
// volatile: 保证多线程可见性
volatile boolean flag;
// synchronized: 同步锁
synchronized void method() { }
// assert: 断言(调试用)
assert x > 0 : "x must be positive";
// enum: 枚举类型 (JDK 5+)
enum Color { RED, GREEN, BLUE }
```
### **2.3 保留字**
```drawio
```
### **2.4 字面量 vs 关键字**
```drawio
```
---
## 三、运算符
### **3.1 运算符分类概览**
```drawio
```
### **3.2 自增自减运算符**
```drawio
```
```
// ═══════════════════════════════════════════════════════════════════════
// 基本用法
// ═══════════════════════════════════════════════════════════════════════
int x = 5;
int a = x++; // a = 5, x = 6 (先赋值给a,再自增)
int b = ++x; // b = 7, x = 7 (先自增,再赋值给b)
System.out.println("a = " + a); // 5
System.out.println("b = " + b); // 7
System.out.println("x = " + x); // 7
// ═══════════════════════════════════════════════════════════════════════
// 图解执行过程
// ═══════════════════════════════════════════════════════════════════════
/*
* int x = 5;
* int a = x++;
*
* 执行过程:
* ┌─────┐ ┌─────┐ ┌─────┐
* │ x=5 │ ──▶ │ a=5 │ ──▶ │ x=6 │
* └─────┘ 先取值 └─────┘ 后自增 └─────┘
*
*
* int b = ++x;
*
* 执行过程:
* ┌─────┐ ┌─────┐ ┌─────┐
* │ x=6 │ ──▶ │ x=7 │ ──▶ │ b=7 │
* └─────┘ 先自增 └─────┘ 后取值 └─────┘
*/
```
**经典面试题**:
```
// ═══════════════════════════════════════════════════════════════════════
// 面试题:计算 y 的值
// ═══════════════════════════════════════════════════════════════════════
int x = 5;
int y = x++ + ++x + x--;
// 详细执行过程分析:
```
```drawio
```
```java
// 验证代码
public class IncrementDemo {
public static void main(String[] args) {
int x = 5;
int y = x++ + ++x + x--;
System.out.println("y = " + y); // 19
System.out.println("x = " + x); // 6
}
}
```
**字节码层面分析**:
```
// 源代码
int i = 1;
i = i++;
// 很多人认为结果是 2,但实际结果是 1!
```
```drawio
```
### **3.3 移位运算符**
```drawio
```
**左移运算 <**<:
```drawio
```
**带符号右移 >>**:
```drawio
```
**无符号右移 >**>>:
```drawio
```
```java
// 移位运算验证代码
public class ShiftDemo {
public static void main(String[] args) {
// 左移
System.out.println("5 << 2 = " + (5 << 2)); // 20
System.out.println("1 << 3 = " + (1 << 3)); // 8
// 带符号右移
System.out.println("20 >> 2 = " + (20 >> 2)); // 5
System.out.println("-8 >> 2 = " + (-8 >> 2)); // -2
// 无符号右移
System.out.println("-8 >>> 2 = " + (-8 >>> 2)); // 1073741822
// 位数超出类型范围时取模
System.out.println("1 << 32 = " + (1 << 32)); // 1 (32 % 32 = 0)
System.out.println("1 << 33 = " + (1 << 33)); // 2 (33 % 32 = 1)
}
}
```
**源码中的移位运算应用**:
```java
// ═══════════════════════════════════════════════════════════════════════
// HashMap 源码:计算哈希值
// ═══════════════════════════════════════════════════════════════════════
static final int hash(Object key) {
int h;
// 将 hashCode 的高 16 位与低 16 位异或
// 目的:让高位也参与索引计算,减少哈希冲突
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
/*
* 图解 hash 函数:
*
* 假设 hashCode = 0b 1010 1010 1010 1010 | 1100 1100 1100 1100
* ─────────高16位────── ─────────低16位──────
*
* h >>> 16: 0b 0000 0000 0000 0000 | 1010 1010 1010 1010
*
* h ^ (h>>>16): 0b 1010 1010 1010 1010 | 0110 0110 0110 0110
* ↑ 高低位信息混合
*/
// ═══════════════════════════════════════════════════════════════════════
// HashMap 源码:计算数组容量(取大于等于 cap 的最小 2 的幂)
// ═══════════════════════════════════════════════════════════════════════
static final int tableSizeFor(int cap) {
int n = cap - 1;
n |= n >>> 1; // 将最高位的 1 右移,与原值或运算
n |= n >>> 2; // 继续扩展
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}
/*
* 图解(假设 cap = 10):
*
* n = 10 - 1 = 9 = 0b 0000 1001
* n >>> 1 = 0b 0000 0100
* n |= n >>> 1 = 0b 0000 1101
* n >>> 2 = 0b 0000 0011
* n |= n >>> 2 = 0b 0000 1111
* ...
* 最终 n = 15, n + 1 = 16 (2⁴)
*/
// ═══════════════════════════════════════════════════════════════════════
// 快速乘除 2 的幂次
// ═══════════════════════════════════════════════════════════════════════
int x = 10;
int multiply8 = x << 3; // x * 8, 比 x * 8 更快
int divide4 = x >> 2; // x / 4, 比 x / 4 更快
// ═══════════════════════════════════════════════════════════════════════
// 权限控制(位标志)
// ═══════════════════════════════════════════════════════════════════════
public class Permission {
public static final int READ = 1 << 0; // 0001 = 1
public static final int WRITE = 1 << 1; // 0010 = 2
public static final int EXECUTE = 1 << 2; // 0100 = 4
public static final int DELETE = 1 << 3; // 1000 = 8
private int permissions = 0;
// 添加权限
public void addPermission(int permission) {
permissions |= permission; // 0101 | 0010 = 0111
}
// 移除权限
public void removePermission(int permission) {
permissions &= ~permission; // 0111 & 1101 = 0101
}
// 检查权限
public boolean hasPermission(int permission) {
return (permissions & permission) == permission;
}
public static void main(String[] args) {
Permission p = new Permission();
p.addPermission(READ | WRITE); // 授予读写权限
System.out.println(p.hasPermission(READ)); // true
System.out.println(p.hasPermission(DELETE)); // false
}
}
```
**移位运算注意事项**:
```drawio
```
---
## 四、流程控制
### **4.1 流程控制分类**
```drawio
```
### **4.2 continue、break、return 对比**
```drawio
```
**图解执行流程**:
```drawio
```
**代码示例**:
```java
public class FlowControlDemo {
public static void main(String[] args) {
// ═══════════════════════════════════════════════════════════════
// continue 示例:跳过偶数
// ═══════════════════════════════════════════════════════════════
System.out.println("=== continue 示例 ===");
for (int i = 0; i < 10; i++) {
if (i % 2 == 0) {
continue; // 跳过偶数
}
System.out.print(i + " "); // 输出: 1 3 5 7 9
}
System.out.println();
// ═══════════════════════════════════════════════════════════════
// break 示例:找到目标后退出
// ═══════════════════════════════════════════════════════════════
System.out.println("=== break 示例 ===");
int[] nums = {1, 3, 5, 7, 9, 2, 4};
int target = 7;
int index = -1;
for (int i = 0; i < nums.length; i++) {
if (nums[i] == target) {
index = i;
break; // 找到后立即退出,不继续遍历
}
}
System.out.println("找到 " + target + " 在索引 " + index);
// ═══════════════════════════════════════════════════════════════
// return 示例:条件满足时提前返回
// ═══════════════════════════════════════════════════════════════
System.out.println("=== return 示例 ===");
printPositive(-5); // 输出: 数字必须为正数
printPositive(10); // 输出: 正数: 10
}
public static void printPositive(int num) {
if (num <= 0) {
System.out.println("数字必须为正数");
return; // 提前返回,后面的代码不执行
}
System.out.println("正数: " + num);
}
}
```
### **4.3 带标签的 break 和 continue**
```java
// ═══════════════════════════════════════════════════════════════════════
// 问题:如何在嵌套循环中跳出外层循环?
// ═══════════════════════════════════════════════════════════════════════
// ❌ 普通 break 只能跳出内层循环
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (i == 1 && j == 1) {
break; // 只跳出内层 for
}
System.out.println("i=" + i + ", j=" + j);
}
}
// 外层循环还会继续执行 i=2 的情况
// ═══════════════════════════════════════════════════════════════════════
// ✅ 使用带标签的 break
// ═══════════════════════════════════════════════════════════════════════
outer: // 标签
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (i == 1 && j == 1) {
break outer; // 跳出外层循环
}
System.out.println("i=" + i + ", j=" + j);
}
}
// 输出:
// i=0, j=0
// i=0, j=1
// i=0, j=2
// i=1, j=0
// (遇到 i=1, j=1 时跳出外层循环)
// ═══════════════════════════════════════════════════════════════════════
// 带标签的 continue
// ═══════════════════════════════════════════════════════════════════════
outer:
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (j == 1) {
continue outer; // 跳到外层循环的下一次迭代
}
System.out.println("i=" + i + ", j=" + j);
}
}
// 输出:
// i=0, j=0
// i=1, j=0
// i=2, j=0
// (每次 j=1 时跳过内层剩余,进入外层下一次)
```
```drawio
```
### **4.4 实际应用场景**
```java
// ═══════════════════════════════════════════════════════════════════════
// 场景 1:搜索二维数组
// ═══════════════════════════════════════════════════════════════════════
public static int[] findElement(int[][] matrix, int target) {
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
if (matrix[i][j] == target) {
return new int[]{i, j}; // return 最简洁
}
}
}
return null;
}
// ═══════════════════════════════════════════════════════════════════════
// 场景 2:参数校验(卫语句模式)
// ═══════════════════════════════════════════════════════════════════════
public void processOrder(Order order) {
// 卫语句:尽早 return,减少嵌套
if (order == null) {
log.warn("订单为空");
return;
}
if (order.getItems().isEmpty()) {
log.warn("订单项为空");
return;
}
if (order.getStatus() != OrderStatus.PENDING) {
log.warn("订单状态不是待处理");
return;
}
// 正常业务逻辑(不需要嵌套在多层 if 中)
doProcess(order);
}
// ═══════════════════════════════════════════════════════════════════════
// 场景 3:过滤处理(continue 跳过不符合条件的项)
// ═══════════════════════════════════════════════════════════════════════
public void processValidUsers(List users) {
for (User user : users) {
// 跳过无效用户
if (user == null) continue;
if (!user.isActive()) continue;
if (user.getAge() < 18) continue;
// 处理有效用户
sendNotification(user);
}
}
// ═══════════════════════════════════════════════════════════════════════
// 场景 4:限制循环次数或超时退出(break)
// ═══════════════════════════════════════════════════════════════════════
public Data pollWithTimeout(Queue queue, long timeoutMs) {
long startTime = System.currentTimeMillis();
while (true) {
Data data = queue.poll();
if (data != null) {
return data;
}
// 超时退出
if (System.currentTimeMillis() - startTime > timeoutMs) {
break;
}
Thread.sleep(100);
}
return null; // 超时返回 null
}
```
### **4.5 switch 语句增强(JDK 12+)**
```
// ═══════════════════════════════════════════════════════════════════════
// 传统 switch(需要 break)
// ═══════════════════════════════════════════════════════════════════════
int dayOfWeek = 3;
String dayType;
switch (dayOfWeek) {
case 1:
case 2:
case 3:
case 4:
case 5:
dayType = "工作日";
break; // 必须 break,否则会穿透
case 6:
case 7:
dayType = "周末";
break;
default:
dayType = "未知";
break;
}
// ═══════════════════════════════════════════════════════════════════════
// 增强 switch(JDK 12+)- 箭头语法,无需 break
// ═══════════════════════════════════════════════════════════════════════
String dayType = switch (dayOfWeek) {
case 1, 2, 3, 4, 5 -> "工作日"; // 多个值用逗号分隔
case 6, 7 -> "周末";
default -> "未知";
};
// ═══════════════════════════════════════════════════════════════════════
// switch 表达式(JDK 14+)- 使用 yield 返回值
// ═══════════════════════════════════════════════════════════════════════
String description = switch (dayOfWeek) {
case 1 -> "Monday";
case 2 -> "Tuesday";
default -> {
// 需要多行代码时用代码块
String result = "Day " + dayOfWeek;
yield result; // 使用 yield 返回值
}
};
// ═══════════════════════════════════════════════════════════════════════
// 模式匹配 switch(JDK 21+)
// ═══════════════════════════════════════════════════════════════════════
Object obj = "Hello";
String result = switch (obj) {
case Integer i -> "整数: " + i;
case String s -> "字符串: " + s;
case Long l -> "长整数: " + l;
case null -> "空值";
default -> "其他类型";
};
```
---
## 五、总结
```drawio
```