怎么用这一页
这是一张查阅表,不是教程。每个条目只给最小可用的写法和一两条注意点;需要解释时,回到对应章节。示例默认在 JDK 25 下编译,标注「21+」的语法在 JDK 21 也可用。
程序结构
package com.plume.library;
import java.util.List;
public final class LibraryApp {
public static void main(String[] args) {
System.out.println("hello");
}
}
| 规则 | 说明 |
|---|
| 一个文件一个 public 类 | 文件名必须与 public 类名一致 |
| 包声明必须在最前 | package 之前只能有注释 |
main 签名 | public static void main(String[] args) |
| 大小写敏感 | String 不是 string |
基本类型
| 类型 | 宽度 | 范围/精度 | 默认值 | 包装类 |
|---|
byte | 8 位 | -128 ~ 127 | 0 | Byte |
short | 16 位 | -32768 ~ 32767 | 0 | Short |
int | 32 位 | -2³¹ ~ 2³¹-1 | 0 | Integer |
long | 64 位 | -2⁶³ ~ 2⁶³-1 | 0L | Long |
float | 32 位 | 约 7 位十进制有效数字 | 0.0f | Float |
double | 64 位 | 约 15 位十进制有效数字 | 0.0d | Double |
char | 16 位 | UTF-16 代码单元 | \u0000 | Character |
boolean | 1 位(语义) | true / false | false | Boolean |
int count = 42;
long total = 42L;
double ratio = 0.5;
char grade = 'A';
boolean active = true;
注意:
- 整数默认是
int,超过 21 亿要加 L。 - 浮点默认是
double,float 要加 f。 - 包装类型是对象,可以为
null;基本类型不能。 - 自动装箱/拆箱有成本,循环里大量装箱会慢。
变量与常量
int count = 0; // 可变
final int limit = 10; // 常量,不能重新赋值
var books = new ArrayList<Book>(); // 局部变量类型推断(10+)
| 写法 | 适用场景 |
|---|
var x = expr; | 局部变量,右侧能明确推断类型 |
final var x = expr; | 局部常量 |
static final | 类级常量 |
final 字段 | 构造器里赋值一次 |
var 不能用于字段、方法参数、返回值,也不能声明为 null。
运算符
| 类别 | 运算符 | 注意 |
|---|
| 算术 | + - * / % | 整数除法截断 |
| 比较 | == != > < >= <= | 对象 == 比较引用 |
| 逻辑 | && || ! | 短路求值 |
| 位运算 | & | ^ ~ << >> >>> | >>> 无符号右移 |
| 赋值 | = += -= *= /= | 复合赋值隐含强制转换 |
| 三元 | cond ? a : b | 两分支类型要兼容 |
| 自增 | ++ -- | 前缀/后缀结果不同 |
int a = 7 / 2; // 3
double b = 7 / 2.0; // 3.5
int c = Integer.MAX_VALUE + 1; // -2147483648(溢出)
控制流
if (count > 0) {
// ...
} else if (count == 0) {
// ...
} else {
// ...
}
for (int i = 0; i < 10; i++) { }
for (Book book : books) { }
while (condition) { }
do { } while (condition);
switch 表达式(21+):
String label = switch (status) {
case AVAILABLE -> "可借";
case BORROWED -> "已借出";
case LOST -> "遗失";
};
带 yield 的块形式:
int days = switch (status) {
case AVAILABLE -> 0;
case BORROWED -> {
int base = 14;
yield base;
}
case LOST -> 999;
};
方法与参数
public static int add(int a, int b) {
return a + b;
}
public static int sum(int... values) {
int total = 0;
for (int v : values) total += v;
return total;
}
| 概念 | 说明 |
|---|
| 重载 | 方法名相同、参数列表不同 |
| 可变参数 | int...,必须是最后一个参数 |
| 值传递 | Java 只有值传递;对象传的是引用的值 |
| 返回 | 用 return;void 方法可以省略 |
类与对象
public class Book {
private final String isbn;
private String title;
public Book(String isbn, String title) {
this.isbn = isbn;
this.title = title;
}
public String title() {
return title;
}
public void rename(String newTitle) {
this.title = Objects.requireNonNull(newTitle);
}
}
| 修饰符 | 作用 |
|---|
private | 仅本类可见 |
| 默认(无修饰符) | 同包可见 |
protected | 同包 + 子类 |
public | 所有地方可见 |
static | 属于类,不属于实例 |
final | 类不可继承 / 方法不可重写 / 字段不可赋值 |
接口、抽象类与继承
public interface LibraryRepository {
Optional<Book> findByIsbn(String isbn);
default boolean exists(String isbn) {
return findByIsbn(isbn).isPresent();
}
}
public abstract class AbstractRepository<T> {
public abstract Optional<T> findById(String id);
}
public final class InMemoryLibraryRepository implements LibraryRepository {
private final Map<String, Book> books = new HashMap<>();
@Override
public Optional<Book> findByIsbn(String isbn) {
return Optional.ofNullable(books.get(isbn));
}
}
| 选择 | 什么时候用 |
|---|
| 接口 | 定义能力,允许多实现 |
| 抽象类 | 共享部分实现,单继承 |
default 方法 | 给接口加方法而不破坏实现类 |
sealed | 限制谁能实现/继承(17+) |
record、enum 与 sealed
public record Book(String isbn, String title, String author) {
public Book {
Objects.requireNonNull(isbn);
if (isbn.isBlank()) throw new IllegalArgumentException("isbn");
}
}
public enum LoanStatus {
BORROWED, RETURNED, OVERDUE
}
public sealed interface Command permits AddBook, ListBooks, BorrowBook { }
public record AddBook(String isbn, String title) implements Command { }
public record ListBooks() implements Command { }
public record BorrowBook(String isbn, String memberId) implements Command { }
| 类型 | 用途 | 注意 |
|---|
record | 不可变数据载体 | 自动生成构造器、访问器、equals、hashCode、toString |
enum | 固定常量集合 | 可以有字段、方法、构造器 |
sealed | 封闭继承体系 | 子类必须 final、sealed 或 non-sealed |
泛型
public interface Repository<T, ID> {
Optional<T> findById(ID id);
void save(T entity);
List<T> findAll();
}
public final class InMemoryRepository<T, ID> implements Repository<T, ID> {
private final Map<ID, T> store = new HashMap<>();
public Optional<T> findById(ID id) { return Optional.ofNullable(store.get(id)); }
public void save(T entity) { /* ... */ }
public List<T> findAll() { return List.copyOf(store.values()); }
}
| 写法 | 含义 |
|---|
<T> | 类型参数 |
List<? extends Number> | 上界通配符,只读 |
List<? super Integer> | 下界通配符,可写 |
<T extends Comparable<T>> | 有界类型参数 |
T 不能 new | 类型擦除,运行时不知道 T 是什么 |
PECS 记忆:Producer Extends, Consumer Super。 只读取用 extends,只写入用 super。
集合
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
Set<String> set = new HashSet<>();
set.add("a");
Map<String, Integer> counts = new HashMap<>();
counts.put("a", 1);
counts.merge("a", 1, Integer::sum);
| 接口 | 常用实现 | 特点 |
|---|
List | ArrayList、LinkedList | 有序、可重复 |
Set | HashSet、LinkedHashSet、TreeSet | 不重复 |
Map | HashMap、LinkedHashMap、TreeMap | 键值对 |
Queue | ArrayDeque、PriorityQueue | 队列/优先队列 |
Deque | ArrayDeque | 双端队列 |
常用工厂:
List<String> fixed = List.of("a", "b"); // 不可变
List<String> copy = List.copyOf(fixed); // 不可变副本
Map<String, Integer> map = Map.of("a", 1); // 不可变
Stream
List<String> titles = books.stream()
.filter(b -> b.title().contains("Java"))
.map(Book::title)
.sorted()
.toList();
Map<String, Long> byAuthor = books.stream()
.collect(Collectors.groupingBy(Book::author, Collectors.counting()));
| 操作 | 类型 | 说明 |
|---|
filter、map、sorted | 中间操作 | 惰性,不触发执行 |
collect、toList、count | 终端操作 | 触发执行 |
findFirst、anyMatch | 短路终端操作 | 找到即停 |
flatMap | 中间操作 | 展平嵌套结构 |
注意:Stream 只能消费一次;parallelStream() 不总是更快,I/O 和锁竞争场景要谨慎。
异常
try {
service.borrow(isbn, memberId);
} catch (BookNotAvailableException e) {
System.err.println("借阅失败:" + e.getMessage());
} finally {
// 总会执行
}
try (BufferedReader reader = Files.newBufferedReader(path)) {
// 自动关闭
}
| 类型 | 是否受检 | 典型 |
|---|
Exception 的子类(非 RuntimeException) | 受检 | IOException、SQLException |
RuntimeException 的子类 | 非受检 | NullPointerException、IllegalArgumentException |
Error | 非受检 | OutOfMemoryError、StackOverflowError |
自定义异常:
public class LibraryException extends RuntimeException {
public LibraryException(String message) { super(message); }
}
public class BookNotAvailableException extends LibraryException {
public BookNotAvailableException(String isbn) {
super("图书不可借:" + isbn);
}
}
文件与 NIO
Path path = Path.of("data", "books.csv");
String content = Files.readString(path, StandardCharsets.UTF_8);
Files.writeString(path, content, StandardCharsets.UTF_8);
List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);
try (Stream<String> stream = Files.lines(path, StandardCharsets.UTF_8)) {
stream.forEach(System.out::println);
}
| 方法 | 用途 |
|---|
Files.exists、Files.isDirectory | 判断 |
Files.createDirectories | 递归建目录 |
Files.list | 列一层 |
Files.walk | 递归遍历 |
Files.copy、Files.move、Files.delete | 复制/移动/删除 |
Files.newBufferedReader | 缓冲字符读取 |
java.time
LocalDate today = LocalDate.now();
LocalDate due = today.plusDays(14);
Instant now = Instant.now();
ZonedDateTime local = now.atZone(ZoneId.of("Asia/Shanghai"));
Duration d = Duration.between(now, now.plusSeconds(90));
Period p = Period.between(today, due);
| 类型 | 表示 |
|---|
LocalDate | 日期,无时间、无时区 |
LocalTime | 时间,无日期、无时区 |
LocalDateTime | 日期 + 时间,无时区 |
Instant | 时间线上的瞬间,UTC |
ZonedDateTime | 带时区的日期时间 |
Duration | 时间量(秒/纳秒) |
Period | 日期量(年/月/日) |
格式化:
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
String text = today.format(fmt);
LocalDate parsed = LocalDate.parse("2026-10-27", fmt);
正则
Pattern pattern = Pattern.compile("^978-\\d{10}$");
Matcher matcher = pattern.matcher(isbn);
if (matcher.matches()) {
// ...
}
| 写法 | 含义 |
|---|
^ $ | 行首/行尾 |
\d \w \s | 数字/单词字符/空白 |
* + ? | 0+ / 1+ / 0或1 |
{n,m} | n 到 m 次 |
() | 捕获组 |
(?:) | 非捕获组 |
(?i) | 忽略大小写 |
注意:Java 字符串里反斜杠要写两次,\d 写成 "\\d"。
常用命令
# 编译
javac -d out src/main/java/com/plume/library/LibraryApp.java
# 运行
java -cp out com.plume.library.LibraryApp list
# 反汇编
javap -c -p out/com/plume/library/LibraryApp.class
# Maven
mvn -q compile
mvn -q test
mvn -q package
mvn -q dependency:tree
# 版本
java -version
javac -version
mvn -version
版本速查
| 特性 | 最低版本 | 备注 |
|---|
var | 10 | 局部变量 |
文本块 """ | 15 | 多行字符串 |
record | 16 | 不可变数据载体 |
sealed | 17 | 封闭继承 |
instanceof 模式匹配 | 16 | 类型判断 + 绑定 |
switch 模式匹配 | 21 | 正式 |
| 记录模式 | 21 | 解构 record |
| 虚拟线程 | 21 | 正式 |
| 模块导入声明 | 25 | 正式 |
紧凑源文件 / 实例 main | 25 | 正式 |
| 灵活构造器 | 25 | 正式 |
| Scoped Values | 25 | 正式 |
一页记忆
- 类型:8 种基本类型 + 引用类型;包装类型可为
null。 - 变量:局部用
var,常量用 final,类常量用 static final。 - 流程:
if/for/while 是语句,switch 可以是表达式。 - 方法:只有值传递;重载看参数列表;可变参数放最后。
- 对象:
private 字段 + 构造器 + 方法;不可变优先。 - 抽象:接口定义能力,抽象类共享实现,
sealed 封口。 - 泛型:
T 是编译期参数,运行时被擦除;PECS 选通配符。 - 集合:
List 有序可重复,Set 不重复,Map 键值对。 - Stream:中间操作惰性,终端操作触发;只能消费一次。
- 异常:受检必须处理,非受检通常表示编程错误;资源用 try-with-resources。
- 时间:用
java.time,不要用 Date/Calendar。 - 文件:用
Path/Files,显式指定 UTF-8。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。