Java 标准库按包速查。每条给包定位、高频类与惯用法、以及该包的坑。JDK 附带这套库是 Java 生态的地基,覆盖日常工程 90% 的包。
1. java.lang – 语言核心(免 import)
描述
编译器自动导入的包:Object、String、包装类、Math、System、Thread、Class、Enum、Record、Runtime。是所有 Java 程序的基础。
语法和示例
// 全部免 import
String s; Integer i; Math.max(1, 2);
System.out.println("x"); // 标准输出
System.err.println("err"); // 错误流
System.currentTimeMillis(); // 毫秒时间戳
System.nanoTime(); // 纳秒(测耗时专用)
System.getenv("HOME");
System.getProperty("user.dir");
System.exit(0); // 0 = 正常退出
System.arraycopy(src, 0, dst, 0, n);
Thread.currentThread().getName();
Thread.sleep(1000); // 受检 InterruptedException
Runtime.getRuntime().availableProcessors();
Runtime.getRuntime().maxMemory();
Class<?> c = obj.getClass();注意事项
- System.currentTimeMillis 用于时间戳,测耗时用 nanoTime(不受系统时钟调整影响)
- System.exit(0) 会跳过 finally 与 shutdown hook 之外的所有清理
- Thread.sleep 抛受检异常,且 sleep(0) 只是让出 CPU 不保证任何等待
- System.arraycopy 是本地方法,比循环赋值快,但两个数组类型必须兼容
- Runtime 是单例,只能通过 getRuntime() 获取
2. java.util – 集合与基础工具
描述
集合框架(List/Set/Map/Queue)+ Arrays/Collections/Objects/Optional/UUID/Scanner/StringJoiner/Base64/Date(遗留)。日常使用频率最高的包。
语法和示例
var uuid = UUID.randomUUID();
var sc = new Scanner(System.in);
int n = sc.nextInt();
var arr = new int[]{3, 1, 2};
Arrays.sort(arr);
var joiner = new StringJoiner(", ", "[", "]");
joiner.add("a").add("b").toString(); // [a, b]
// Base64
Base64.getEncoder().encodeToString(bytes);
Base64.getDecoder().decode(str);
Base64.getUrlEncoder().withoutPadding();
// 遗留日期(新代码用 java.time)
new java.util.Date(); Calendar.getInstance();注意事项
- java.util.Date 与 Calendar 可变且月份从 0 开始——新代码一律用 java.time
- Scanner 在大量输入时较慢,读大文件用 BufferedReader
- UUID.randomUUID 是 v4(随机),不保证字典序,不能当主键排序用
- StringJoiner 适合已知分隔符/前后缀的拼接,比手写判断首尾简洁
- Base64 有 Basic/URL/MIME 三种变体,URL 场景必须用 getUrlEncoder
3. java.util.concurrent – 并发工具
描述
线程池、Future、并发集合、原子类、锁、同步器(Latch/Barrier/Semaphore)。Java 并发的核心包。
语法和示例
// 线程池(推荐显式参数)
var pool = new ThreadPoolExecutor(
4, 8, 60, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(100),
new ThreadPoolExecutor.CallerRunsPolicy());
pool.submit(() -> work());
pool.shutdown(); pool.awaitTermination(30, TimeUnit.SECONDS);
// 异步编排
CompletableFuture.supplyAsync(() -> fetch(a), pool)
.thenApply(this::parse)
.exceptionally(e -> fallback)
.join();
// 并发集合与原子
var map = new ConcurrentHashMap<String, Integer>();
map.merge(k, 1, Integer::sum);
var counter = new AtomicInteger();
counter.incrementAndGet();
counter.compareAndSet(0, 1);
// 同步器
var latch = new CountDownLatch(3);
latch.countDown(); latch.await();
var sem = new Semaphore(10); // 限流
sem.acquire(); sem.release();注意事项
- Executors 工厂方法(newFixedThreadPool)用无界队列,高负载会 OOM——显式构造更安全
- CallerRunsPolicy 提供背压(满了让提交线程自己跑),比直接丢弃更可控
- CompletableFuture 的默认线程池是 ForkJoinPool.commonPool,IO 任务会拖垮它——显式传自己的池
- ConcurrentHashMap 的 size() 在高并发下不精确,只能当参考值
- CountDownLatch 一次性,可复用场景用 CyclicBarrier
4. java.util.stream – 流式处理
描述
与集合配合的声明式管道,也可从 IO/文件/生成器建流。原始流(IntStream/LongStream)避免装箱。
语法和示例
IntStream.range(0, 10).filter(x -> x % 2 == 0).toArray();
Stream.of("a", "b").collect(Collectors.toList());
list.parallelStream().mapToLong(Item::weight).sum();
// 从文件建流(注意需关闭)
try (var lines = Files.lines(path)) {
long n = lines.filter(l -> !l.isBlank()).count();
}
// 生成无限流 + 截断
Stream.iterate(0, x -> x + 1).limit(10).forEach(System.out::println);
Stream.generate(Math::random).limit(5);
// 分组后的下游收集器
orders.stream().collect(Collectors.groupingBy(
Order::customer, Collectors.summingInt(Order::amount)));注意事项
- Files.lines 返回的流持有文件句柄,必须 try-with-resources 关闭
- parallelStream 用 ForkJoinPool.commonPool,IO 阻塞会拖累全应用
- 惰性流 + 无限流必须配 limit,否则永不结束
- collect(Collectors.toList()) 在 16+ 可用 toList() 替代(后者不可变)
- 流里做副作用(修改外部集合)在并发流下不可预测
5. java.io – 传统 IO(字节流与字符流)
描述
字节流 InputStream/OutputStream,字符流 Reader/Writer。装饰器模式层层包装(缓冲、转换、打印)。新项目读写文件优先 java.nio.file。
语法和示例
try (var in = new BufferedInputStream(new FileInputStream("a.bin"))) {
in.readAllBytes();
}
try (var r = new BufferedReader(new FileReader("a.txt"))) {
r.lines().forEach(System.out::println);
}
try (var w = new PrintWriter(new FileWriter("out.txt"))) {
w.println("hi");
}
// 转换流:字节 ↔ 字符(指定编码)
new InputStreamReader(in, StandardCharsets.UTF_8);
new OutputStreamWriter(out, StandardCharsets.UTF_8);
// 读控制台
var sc = new Scanner(System.in);
sc.nextLine();注意事项
- FileReader/FileWriter 用平台默认编码——跨平台乱码根源,必须显式用 InputStreamReader 指定 UTF-8
- 包装顺序很重要:缓冲流要包在底层流外面,不要反过来
- close 只需关最外层(关闭会传递),但 try-with-resources 会自动管理
- readAllBytes 大文件会 OOM——大文件必须流式处理
- PrintWriter 默认吞异常(checkError 才知是否失败),关键写入用 PrintStream 更明确
6. java.nio.file – 现代文件 IO(Files/Path)
描述
Path 替代 File(更语义化、跨平台);Files 一个类覆盖读写、复制、遍历、属性、临时文件。NIO.2 是 Java 7+ 的标准做法。
语法和示例
Path p = Path.of("data", "a.txt"); // 跨平台拼接
Path abs = p.toAbsolutePath();
Files.exists(p); Files.isDirectory(p); Files.size(p);
Files.readString(p); // 默认 UTF-8
Files.writeString(p, "内容");
Files.readAllLines(p);
Files.copy(src, dst, StandardCopyOption.REPLACE_EXISTING);
Files.move(a, b);
Files.createDirectories(Path.of("x/y/z")); // 递归建
Files.deleteIfExists(p);
// 遍历目录
try (var s = Files.walk(Path.of("logs"))) {
s.filter(f -> f.toString().endsWith(".log")).forEach(this::archive);
}
Files.list(dir); // 仅一层
// 临时文件
Files.createTempFile("pre", ".tmp");
Files.createTempDirectory("work");
// 属性
Files.getLastModifiedTime(p);
Files.readAttributes(p, BasicFileAttributes.class);注意事项
- Files.walk 返回的 Stream 必须关闭(try-with-resources),否则句柄泄漏
- Files.readString 默认 UTF-8(与老的 FileReader 相反),读非 UTF-8 文件需显式传编码
- Files.delete 对非空目录抛异常,删目录树要先遍历再删
- Path.resolve 是拼接,Path.relativize 求相对路径,别混用
- 跨文件系统 move 可能退化为 copy+delete(可用 ATOMIC_MOVE 检测)
7. java.time – 日期时间(包级速查)
描述
不可变、线程安全的时间 API。LocalXxx 无时区,ZonedDateTime 带时区,Instant 是 UTC 绝对时刻。取代 Date/Calendar。
语法和示例
LocalDate.now(); LocalTime.now(); LocalDateTime.now();
LocalDate.parse("2026-10-29");
ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
Instant.now(); Instant.now().getEpochSecond();
// 与时区/时间戳互转
instant.atZone(zone); zdt.toInstant();
Date.from(instant); instant.toEpochMilli();
// 格式化(线程安全)
DateTimeFormatter.ofPattern("yyyyMMdd");
DateTimeFormatter.ISO_INSTANT;
// 可注入时钟便于测试
Clock.systemUTC(); Clock.fixed(instant, zone);
LocalDate.now(clock);注意事项
- LocalDateTime 无时区——跨时区存储与比较一律用 Instant
- DateTimeFormatter 不可变可复用,作静态字段避免重复创建
- Clock 可注入使时间可控——测试友好,生产用 systemUTC/systemDefaultZone
- 月份从 1 开始(LocalDate.of(2026, 1, 1) 是 1 月)
- Duration 与 Period 不能互转(一个是时间量一个是日期量)
8. java.net.http – HttpClient(11+)
描述
现代 HTTP 客户端:同步/异步、HTTP/2、WebSocket、请求超时。取代 HttpURLConnection。
语法和示例
var client = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(5))
.followRedirects(HttpClient.Redirect.NORMAL)
.build();
var req = HttpRequest.newBuilder(URI.create("https://api.example.com"))
.header("Accept", "application/json")
.timeout(Duration.ofSeconds(10))
.GET()
.build();
var resp = client.send(req, HttpResponse.BodyHandlers.ofString());
resp.statusCode(); resp.body(); resp.headers();
// 异步
client.sendAsync(req, HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println);
// POST JSON
HttpRequest.newBuilder(uri)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(json))
.build();注意事项
- HttpClient 应复用(内部有连接池),每次请求都 new 会耗尽连接
- BodyHandlers.ofString() 用默认编码,指定 UTF-8 用 ofString(StandardCharsets.UTF_8)
- sendAsync 返回 CompletableFuture,异常需 exceptionally/handle 处理,否则静默丢失
- 超时有两级:connectTimeout(建连)与 request.timeout(整体)
- 没有请求体时不要传 BodyPublishers.noBody() 之外的构造(GET 默认无体)
9. java.net – URI/URL/网络基础
描述
URI(语法解析)与 URL(含访问能力);InetAddress、Socket、ServerSocket;编码工具。
语法和示例
URI uri = URI.create("https://a.b/x?page=2#frag");
uri.getHost(); uri.getPath(); uri.getQuery();
uri.resolve("other"); // 相对路径解析
URLEncoder.encode("中文", StandardCharsets.UTF_8);
URLDecoder.decode(enc, StandardCharsets.UTF_8);
InetAddress.getByName("blog.x-rush.cn").getHostAddress();
InetAddress.getLocalHost();
// 简易服务器
try (var server = new ServerSocket(8080);
var sock = server.accept()) {
sock.getInputStream().readAllBytes();
}
// Socket 客户端
try (var s = new Socket("host", 80)) {
s.getOutputStream().write(bytes);
}注意事项
- URL 的 equals 会发起 DNS 解析(阻塞),比较字符串用 URI 而非 URL
- URLEncoder 编码的是表单语义(空格→+),URL 路径段要用 URI 的编码方式
- ServerSocket.accept 阻塞,生产用 NIO/NIO2 或框架
- Socket 读写有超时(setSoTimeout),默认无限等待
- InetAddress.getByName 会查 DNS,结果缓存受 JVM 配置影响
10. java.sql / JDBC – 数据库访问
描述
DriverManager 建连、Connection/PreparedStatement/ResultSet 三层。生产必须用连接池(HikariCP 等)与预处理语句。
语法和示例
try (var conn = DriverManager.getConnection(url, user, pass);
var ps = conn.prepareStatement(
"SELECT id, name FROM users WHERE k = ?")) {
ps.setString(1, key);
try (var rs = ps.executeQuery()) {
while (rs.next()) {
rs.getLong("id");
rs.getString("name");
}
}
}
// 事务
conn.setAutoCommit(false);
try { /* 多条语句 */ conn.commit(); }
catch (Exception e) { conn.rollback(); throw e; }
// 批量
ps.addBatch(); ps.executeBatch();注意事项
- Connection/Statement/ResultSet 必须关闭,否则连接泄漏——一律 try-with-resources
- 拼接 SQL 字符串 = SQL 注入,永远用 PreparedStatement 参数
- ResultSet 的列索引从 1 开始(不是 0)
- setAutoCommit(false) 后忘记 commit 会导致数据丢失且连接归还时状态混乱
- 生产用连接池:每次 DriverManager.getConnection 都是新建物理连接,极慢
11. java.security / javax.crypto – 加密
描述
MessageDigest 摘要、SecureRandom 强随机、Cipher 对称加解密、KeyGenerator 密钥生成。
语法和示例
var md = MessageDigest.getInstance("SHA-256");
md.digest(data);
// 强随机
var rnd = SecureRandom.getInstanceStrong(); // 可能阻塞(熵不足)
new SecureRandom().nextInt(100); // 一般场景用这个
// 对称加密 AES-GCM(现代推荐模式)
var cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, key, new GCMParameterSpec(128, iv));
cipher.doFinal(plain);
// 密钥
KeyGenerator.getInstance("AES").generateKey();注意事项
- MD5/SHA-1 已不适合安全场景(碰撞),用 SHA-256 及以上
- 密码不要用摘要,用 BCrypt/Argon2(加盐 + 慢哈希)
- SecureRandom.getInstanceStrong 在熵池不足时会阻塞(Linux 早期启动)
- AES 的 IV 每次加密必须不同,GCM 模式下 IV 复用是致命错误
- 别自己实现加密协议,用成熟库(Tink/BouncyCastle)
12. java.text – 格式化与国际化
描述
NumberFormat/DecimalFormat(数字)、Collator(按语言排序)、DateFormat 已被 java.time 取代。
语法和示例
var df = new DecimalFormat("#,##0.00");
df.format(1234567.891); // 1,234,567.89
NumberFormat.getCurrencyInstance(Locale.CHINA).format(99.5);
NumberFormat.getPercentInstance().format(0.25);
// 按语言排序(中文拼音)
var cn = Collator.getInstance(Locale.CHINA);
words.sort(cn);
// MessageFormat 占位符
MessageFormat.format("{0} 有 {1} 条", name, n);注意事项
- SimpleDateFormat 线程不安全(DateFormat 也是)——新代码用 DateTimeFormatter
- DecimalFormat 的符号变小写/大写有语义(# 不补零,0 补零)
- Collator 的中文排序是拼音序,不是 Unicode 码点序
- NumberFormat 默认按 JVM 默认 Locale,跨语言环境必须显式传 Locale
- MessageFormat 的 {} 会被解析,字符串里含花括号要转义
13. java.util.function – 函数式接口
描述
标准函数式接口四族:Function(转换)、Predicate(判断)、Supplier(提供)、Consumer(消费),以及 Bi/原始类型变体。方法引用四式。
语法和示例
Function<String, Integer> len = String::length;
Predicate<String> empty = String::isEmpty;
Supplier<List<String>> mk = ArrayList::new;
Consumer<String> print = System.out::println;
BiFunction<Integer, Integer, Integer> add = (a, b) -> a + b;
UnaryOperator<String> up = String::toUpperCase;
BinaryOperator<Integer> max = Integer::max;
// 组合
Function<String, String> trimUpper =
((Function<String, String>) String::trim).andThen(String::toUpperCase);
predicate.negate(); predicate.and(other);
// 原始类型变体避免装箱
IntFunction<String> idx = i -> "第" + i;注意事项
- 方法引用四式:类::静态、对象::实例、类::实例方法(第一参作接收者)、类::new
- Function 的 andThen/compose 顺序不同:andThen 先本后他,compose 先他后本
- Predicate.negate 比写 !xxx 更清晰,也便于方法引用传参
- 用 IntFunction/ToIntFunction 等原始类型变体避免装箱开销
- 自定义函数式接口要标 @FunctionalInterface(编译期检查单方法约束)
14. java.util.regex – 正则
描述
Pattern 预编译(复用提升性能)、Matcher 执行、命名组便于取值。PatternSyntaxException 在编译期暴露问题。
语法和示例
var p = Pattern.compile("(\\w+)@(\\w+)");
var m = p.matcher("a@b cc@d");
while (m.find()) {
m.group(0); m.group(1); m.group(2);
}
// 命名组
var named = Pattern.compile("(?<year>\\d{4})-(?<mon>\\d{2})");
named.matcher("2026-10").results()
.forEach(r -> r.group("year"));
// 常用
"a1b2".replaceAll("\\d", "#");
Pattern.compile("\\s+").split(text);
Pattern.matches("^\\d+$", "123");
// 标志
Pattern.compile("abc", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);注意事项
- 在循环里写 String.matches 会每次编译正则——提取 Pattern.compile 到常量
- Java 正则的 \\d 默认匹配 ASCII 数字,Unicode 数字需 UNICODE_CHARACTER_CLASS
- matcher 的 find 与 matches 不同:matches 要整体匹配,find 找子串
- group 数量超 9 时用命名组,避免数括号
- 回溯灾难(如 (a+)+b)会让正则指数级变慢——限制输入长度或用占有量词
15. java.util.logging / SLF4J – 日志
描述
JUL 是 JDK 内置日志(可用但生态弱);生产工程事实标准是 SLF4J 门面 + Logback/Log4j2 实现。
语法和示例
// JUL 最低可用集
var log = Logger.getLogger("app");
log.setLevel(Level.INFO);
log.info("started {0}", name);
log.warning("slow");
var h = new FileHandler("app.log", true);
h.setFormatter(new SimpleFormatter());
log.addHandler(h);
// SLF4J(外部依赖,工程主流)
// private static final Logger log = LoggerFactory.getLogger(Foo.class);
// log.info("user {} logged in", id);注意事项
- JUL 的占位符是 {0} 而不是 SLF4J 的 {}——混用不生效
- 日志级别判断不要手写 isDebugEnabled(SLF4J 的 {} 本身惰性)
- 生产日志必须配滚动与保留策略,否则磁盘写满
- 异常日志要传异常对象,不要只 log(e.getMessage())——丢堆栈
- 避免字符串拼接日志:传参数让框架惰性求值
16. JPMS 模块系统(9+)
描述
module-info.java 声明模块名、依赖与导出包。让依赖关系显式化、可做 jlink 裁剪。类路径应用可继续不模块化。
语法和示例
// src/main/java/module-info.java
module com.example.app {
requires java.net.http;
requires transitive com.example.core; // 传递依赖
exports com.example.api; // 对外公开的包
opens com.example.model to com.fasterxml.jackson.databind; // 反射开放
uses com.example.spi.Plugin; // 服务发现
provides com.example.spi.Plugin with com.example.impl.MyPlugin;
}注意事项
- 未 exports 的包即使类是 public 也不可被其他模块访问
- 反射需要 opens(不是 exports)——框架读私有字段必须 opens
- requires transitive 会把依赖传递给下游模块(API 里暴露了某类型时才需要)
- 模块化后 jlink 可裁剪运行时(最小几十 MB),但需全部依赖都是模块
- 兼容策略:不写 module-info 的应用仍以类路径运行,不必强行模块化
17. 常用操作速查表
描述
按「要做什么」直接查该用哪个类。这张表是日常最高频的索引。
语法和示例
<table>
<thead><tr><th>场景</th><th>首选</th></tr></thead>
<tbody><tr><td>读文本文件</td><td>Files.readString / Files.readAllLines</td></tr><tr><td>写文本文件</td><td>Files.writeString</td></tr><tr><td>流式读大文件</td><td>Files.lines / BufferedReader</td></tr><tr><td>遍历目录树</td><td>Files.walk(记得关闭)</td></tr><tr><td>HTTP 请求</td><td>java.net.http.HttpClient(11+)</td></tr><tr><td>JSON 序列化</td><td>外部库:Jackson / Gson</td></tr><tr><td>日期时间</td><td>java.time.LocalDateTime / Instant</td></tr><tr><td>金额计算</td><td>java.math.BigDecimal(字符串构造)</td></tr><tr><td>集合排序</td><td>list.sort(Comparator…)</td></tr><tr><td>分组统计</td><td>stream().collect(groupingBy(...))</td></tr><tr><td>并发任务</td><td>ExecutorService / CompletableFuture</td></tr><tr><td>原子计数</td><td>AtomicInteger / LongAdder</td></tr><tr><td>随机数(安全)</td><td>SecureRandom</td></tr><tr><td>Base64</td><td>java.util.Base64</td></tr><tr><td>压缩</td><td>java.util.zip.GZIPInputStream / ZipOutputStream</td></tr><tr><td>正则</td><td>Pattern.compile 预编译</td></tr><tr><td>命令行参数</td><td>手写解析或外部 picocli</td></tr></tbody></table>注意事项
- 表的价值在于「先查表再写代码」——避免手写已有轮子的逻辑
- JSON 与 YAML JDK 都没有内置,选库时注意维护活跃度
- 表里「首选」是常规场景;特殊需求(超大文件、极低延迟)需另选
- 外部库引入前先确认是否可用 JDK 内置能力替代,减少依赖