Java知识点 #5 速成笔记

发布于:2025-05-24 ⋅ 阅读:(11) ⋅ 点赞:(0)

#5

45.hutool

hutool

工具类库

:比如前面学的网络编程和IO 可以被简单封装为 hutool-socket 使用 AIO NIO BIO

模块

介绍

hutool-aop

JDK动态代理封装,提供非IOC下的切面支持

hutool-bloomFilter

布隆过滤,提供一些Hash算法的布隆过滤

hutool-cache

简单缓存实现

hutool-core

核心,包括Bean操 作、日期、各种Util等

hutool-cron

定时任务模块,提供类Crontab表达式的定时任务

hutool-crypto

加密解密模块,提供对称、非对称和摘要算法封装

hutool-db

JDBC封装后的数据操作,基于ActiveRecord思想

hutool-dfa

基于DFA模型的多关键字查找

hutool-extra

扩展模块,对第三方封装(模板引擎、邮件、Servlet、二维码、Emoji、FTP、分词等)

hutool-http

基于HttpUrlConnection的Http客户端封装

hutool-log

自动识别日志实现的日志门面

hutool-script

脚本执行封装,例如Javascript

hutool-setting

功能更强大的Setting配置文件和Properties封装

hutool-system

系统参数调用封装(JVM信息等)

hutool-json

JSON实现

hutool-captcha

图片验证码实现

hutool-poi

针对POI中Excel和Word的封装

hutool-socket

基于Java的NIO和AIO的Socket封装

hutool-jwt

JSON Web Token (JWT)封装实现


### Hutool工具类详解

#### 一、Hutool简介
**Hutool** 是一个 **Java 工具类库**,旨在通过封装常用功能代码,简化开发流程,提高开发效率。它涵盖了字符串处理、集合操作、IO流、加密解密、日期时间、反射机制等多个领域的工具类,具有 **轻量级、文档齐全、易上手** 的特点,被广泛应用于企业级项目和开源项目中。

#### 二、核心功能模块
Hutool按功能划分为多个模块,以下是主要模块的介绍:


##### 1. 基础工具类(core)
- **字符串处理(StrUtil)**  
  提供字符串判空、拼接、截取、转换(如驼峰转下划线)、编码解码(Base64、URL等)等功能。  
  **示例**:  
  ```java
  String str = "  Hello, Hutool!  ";
  StrUtil.trim(str); // 去除首尾空格,结果:"Hello, Hutool!"
  StrUtil.format("{}是{}工具类", "Hutool", "Java"); // 格式化字符串,结果:"Hutool是Java工具类"
  ```

- **集合工具(CollUtil)**  
  简化集合操作,如判空、转换(数组转集合、集合转Map)、过滤、洗牌等。  
  **示例**:  
  ```java
  List<String> list = CollUtil.newArrayList("a", "b", "c");
  CollUtil.shuffle(list); // 打乱集合顺序
  Map<String, Integer> map = CollUtil.toMap(list, s -> s.length()); // 集合转Map
  ```

- **数组工具(ArrayUtil)**  
  支持数组判空、复制、拼接、反转、排序等操作。  
  **示例**:  
  ```java
  int[] arr = {1, 3, 2};
  ArrayUtil.sort(arr); // 排序后:[1, 2, 3]
  int[] newArr = ArrayUtil.addAll(arr, 4, 5); // 拼接数组:[1, 2, 3, 4, 5]
  ```


##### 2. 日期与时间(date-time)
- **DateUtil**  
  提供日期格式化、加减、比较、时区转换等功能,支持JDK 8+的`LocalDateTime`。  
  **示例**:  
  ```java
  // 当前时间转指定格式
  String now = DateUtil.format(DateUtil.now(), "yyyy-MM-dd HH:mm:ss"); // 结果如:"2025-05-22 14:30:00"
  // 计算两天后的日期
  Date future = DateUtil.offsetDay(new Date(), 2); 
  ```


##### 3. 文件与IO(io)
- **FileUtil**  
  封装文件操作,如创建/删除文件、读取/写入内容、遍历目录、文件压缩(ZIP/TAR)等。  
  **示例**:  
  ```java
  // 读取文件内容为字符串
  String content = FileUtil.readUtf8String("path/to/file.txt"); 
  // 写入内容到文件(自动创建父目录)
  FileUtil.writeUtf8String("Hello, Hutool!", "path/to/new_file.txt"); 
  ```

- **IOUtil**  
  处理流操作,如关闭流、流复制、读取类路径资源等。  
  **示例**:  
  ```java
  // 复制输入流到输出流并自动关闭
  IOUtil.copy(inputStream, outputStream); 
  ```


##### 4. 加密与安全(crypto)
- **加密工具(如DigestUtil、SecureUtil)**  
  支持MD5、SHA、AES、RSA等加密算法,简化加密流程。  
  **示例**:  
  ```java
  // MD5加密
  String md5 = DigestUtil.md5Hex("password"); 
  // AES加密
  AES aes = SecureUtil.aes("密钥".getBytes());
  String encryptStr = aes.encryptBase64("明文内容"); 
  ```


##### 5. 反射与类操作(reflect)
- **ReflectUtil**  
  简化反射调用,如创建对象、调用方法、获取字段等,支持泛型和注解处理。  
  **示例**:  
  ```java
  // 实例化对象(无需手动处理异常)
  User user = ReflectUtil.newInstance(User.class); 
  // 调用方法
  ReflectUtil.invoke(user, "setName", "张三"); 
  ```


##### 6. 网络工具(network)
- **HttpUtil**  
  封装HTTP请求,支持GET/POST请求、表单提交、JSON参数、文件上传等。  
  **示例**:  
  ```java
  // 发送GET请求
  String result = HttpUtil.get("https://api.example.com/data"); 
  // 发送POST请求(JSON参数)
  String json = HttpUtil.post("https://api.example.com/submit", "{\"key\":\"value\"}"); 
  ```


##### 7. 其他常用模块
- **数学工具(NumberUtil)**:数值转换、进制转换、随机数生成等。  
- **正则工具(RegexUtil)**:正则表达式匹配、替换、分组提取等。  
- **系统工具(SystemUtil)**:获取系统信息(如内存、CPU、操作系统)、执行命令等。  


#### 三、Hutool的优势
1. **简化代码**:避免重复编写基础功能代码,如字符串处理、集合操作等。  
2. **一致性**:所有工具类命名规范统一(如`XXXUtil`),方法名直观易读。  
3. **健壮性**:内部处理了空指针、非法参数等常见异常,降低代码崩溃风险。  
4. **集成方便**:通过Maven或Gradle引入依赖即可使用,无需复杂配置。  
   **Maven依赖**:  
   ```xml
   <dependency>
       <groupId>cn.hutool</groupId>

       <artifactId>hutool-all</artifactId>

       <version>5.8.21</version> <!-- 最新版本请查看官网 -->
   </dependency>

   ```


#### 四、使用场景
- **日常开发**:处理字符串、日期、文件等基础需求。  
- **工具类开发**:基于Hutool封装更复杂的业务工具。  
- **快速原型**:在测试或Demo开发中快速实现功能。  
- **开源项目**:许多知名开源项目(如Dromara的Hmily)依赖Hutool提升开发效率。


#### 五、学习资源
- **官方文档**:[Hutool官网](https://hutool.cn/docs/)(提供详细API说明和示例)。  
- **GitHub仓库**:[Hutool GitHub](https://github.com/dromara/hutool)(源码与Issue参考)。  
- **中文社区**:QQ群、Gitter等渠道交流使用问题。


#### 六、注意事项
- **模块选择**:若无需全部功能,可引入单一模块(如`hutool-core`、`hutool-io`)以减少包体积。  
- **版本兼容性**:高版本Hutool可能不兼容低版本JDK(建议使用JDK 8+)。  
- **性能考量**:工具类虽便捷,但在高并发场景下需注意底层实现是否满足性能要求。

通过Hutool,开发者可将更多精力聚焦于业务逻辑,而非重复造轮子。无论是新手还是资深工程师,熟练使用Hutool都能显著提升开发效率。

46.SOCKET

使用Java进行TCP编程时,需要使用Socket模型:教程

  • 服务器端用ServerSocket监听指定端口;
  • 客户端使用Socket(InetAddress, port)连接服务器;
  • 服务器端用accept()接收连接并返回Socket
  • 双方通过Socket打开InputStream/OutputStream读写数据;
  • 服务器端通常使用多线程同时处理多个客户端连接,利用线程池可大幅提升效率;
  • flush()用于强制输出缓冲区到网络。

通信方式

特点

适用场景

Socket

底层网络接口,灵活但需自行处理细节

自定义协议、高性能需求

HTTP

基于请求 - 响应,无状态

网页浏览、RESTful API

RPC

远程过程调用,屏蔽网络细节

微服务内部通信(如 gRPC、Dubbo)

消息队列

异步通信,解耦生产者与消费者

高并发场景、任务调度

  1. TCP Socket

    • 面向连接,使用 Socket(客户端)和 ServerSocket(服务器)。
    • 流程:服务器监听端口 → 客户端连接 → 双向数据流(InputStream/OutputStream)。
    • 示例:java
  1. UDP Socket
    • 无连接,使用 DatagramSocketDatagramPacket
    • 流程:直接发送 / 接收数据包(需指定目标地址和端口)。
    • 适用于实时性要求高的场景(如游戏、音视频)。
  1. 关键注意点
    • 阻塞 IO 需配合多线程处理并发。
    • 需处理网络异常(如超时、断开)。
    • 大数据传输需优化缓冲区。

Socket 是实现 HTTP、数据库连接等上层协议的基础,广泛用于网络通信、分布式系统和微服务架构。

// 服务器:serverSocket.accept() → 获取客户端Socket → 读写数据  
// 客户端:new Socket(host, port) → 读写数据  

47.TCP

Java TCP 基于 SocketServerSocket 实现可靠通信:

  1. 核心机制
    • 三次握手建立连接,四次挥手关闭连接。
    • 基于字节流(InputStream/OutputStream),需自定义协议分隔消息边界(如换行符、长度前缀)。
  1. 并发处理
    • 单线程模型:一次处理一个客户端,其他客户端阻塞。
    • 多线程模型:为每个客户端创建独立线程(需注意资源耗尽风险)。
    • NIO 模型:基于 Selector 实现多路复用,单线程处理多个连接(Java 1.4+)。
  1. 典型问题
    • 粘包 / 半包:通过 BufferedReader 按行读取或自定义解码器解决。
    • 性能瓶颈:使用线程池(Executors.newFixedThreadPool)或异步 IO(Netty 框架)优化。

示例:

java

// 服务器:new ServerSocket(port).accept() → 多线程处理Socket  
// 客户端:new Socket(host, port) → 获取流读写  

48.UDP

Java UDP 基于 DatagramSocketDatagramPacket 实现无连接通信:

  1. 核心机制
    • 无需握手,直接发送数据包(send()/receive())。
    • 数据包包含源 / 目标 IP + 端口,最大 65,507 字节(受限于底层协议)。
  1. 关键特性
    • 不可靠:可能丢包、乱序、重复。
    • 低延迟:无需建立连接,适合实时场景(如游戏、音视频)。
  1. 编程模型
    • 服务器:绑定端口 → 循环接收数据包(receive() 阻塞)。
    • 客户端:指定目标地址发送数据包。
    • 示例:java
// 发送:new DatagramPacket(data, len, address, port)  
// 接收:packet.getAddress() 获取发送方地址  
  1. 典型问题
    • 丢包处理:应用层实现确认机制(如序列号、超时重传)。
    • 半包问题:UDP 不存在粘包,但需自行处理大数据分片(如手动拆包 / 组包)。

相比 TCP,UDP 更轻量但需应用层补充可靠性逻辑。

49.打印流

打印流(PrintStream/PrintWriter)是 Java 简化输出操作的高级流,核心特性:

  1. 自动刷新:写入换行符或调用 println() 时自动刷新缓冲区。
  1. 格式化输出:支持 printf() 语法(如 %.2f)。
  1. 异常处理:方法不抛 IOException,通过 checkError() 检查。

区别

  • PrintStream(字节流):适合二进制数据,默认平台编码。
  • PrintWriter(字符流):适合文本,需显式指定编码(如 UTF-8)。

典型场景
日志输出、数据导出、控制台打印、网络通信。
注意

  • 使用 try-with-resources 确保资源关闭。
  • 大数据量时用 BufferedWriter 提升性能。

打印流通过封装底层细节,大幅提升输出效率与代码可读性。

### Java 打印流(PrintStream/PrintWriter)详解

#### 一、打印流是什么?
**打印流** 是 Java 提供的用于简化输出操作的高级流,它封装了底层输出流,并提供了一系列 **print()** 和 **println()** 方法,支持自动换行、格式化输出(如 `printf()`),且无需手动处理 `IOException`。

Java 提供两种打印流:
- **PrintStream**:字节流,处理原始字节数据(如文件、网络)。
- **PrintWriter**:字符流,处理字符数据(如文本),更适合国际化场景。


#### 二、核心特性与优势

##### 1. 自动刷新
打印流可在以下情况自动刷新缓冲区:
- 写入换行符(`\n`)时。
- 调用 `println()` 方法时。
- 构造时指定 `autoFlush = true`(仅对 `println()`、`printf()`、`format()` 有效)。

**示例**:
```java
// 创建自动刷新的 PrintWriter
PrintWriter writer = new PrintWriter(new FileWriter("output.txt"), true);
writer.println("Hello, World!"); // 自动刷新缓冲区
```

##### 2. 格式化输出
支持类似 C 语言 `printf` 的格式化语法:
```java
double pi = Math.PI;
System.out.printf("PI 的值是: %.2f%n", pi); // 输出:PI 的值是: 3.14
```

##### 3. 异常处理简化
打印流的方法不会抛出 `IOException`,而是通过 `checkError()` 方法检查底层错误:
```java
PrintWriter writer = new PrintWriter("file.txt");
writer.println("Data");
if (writer.checkError()) { // 检查并重置错误状态
    System.err.println("写入失败");
}
```


#### 三、PrintStream vs PrintWriter
| **特性**               | **PrintStream**              | **PrintWriter**              |
|------------------------|------------------------------|------------------------------|
| **继承关系**           | 继承自 `OutputStream`(字节流) | 继承自 `Writer`(字符流)     |
| **处理数据类型**       | 字节(byte)                 | 字符(char)和字符串(String) |
| **编码支持**           | 需手动指定(如 `new PrintStream(file, "UTF-8")`) | 构造时直接指定编码(如 `new PrintWriter(file, "UTF-8")`) |
| **国际化支持**         | 弱(字节流)                 | 强(字符流,自动处理编码)   |
| **应用场景**           | 输出二进制数据(如文件、网络) | 输出文本数据(如日志、配置) |


#### 四、常见用法示例

##### 1. 输出到控制台
```java
System.out.println("控制台输出"); // System.out 是 PrintStream
System.err.println("错误输出");   // System.err 也是 PrintStream
```

##### 2. 输出到文件
```java
// 使用 PrintWriter 输出文本文件(自动刷新)
try (PrintWriter writer = new PrintWriter(new FileWriter("output.txt"), true)) {
    writer.println("第一行");
    writer.printf("格式化输出: %d, %s%n", 123, "abc");
} catch (IOException e) {
    e.printStackTrace();
}

// 使用 PrintStream 输出二进制文件
try (PrintStream ps = new PrintStream(new FileOutputStream("data.bin"))) {
    ps.write(65); // 写入字节 'A'
    ps.println(123); // 写入数字(转为字符串)
} catch (IOException e) {
    e.printStackTrace();
}
```

##### 3. 重定向标准输出
```java
// 将 System.out 重定向到文件
PrintStream fileOut = new PrintStream("log.txt");
System.setOut(fileOut);
System.out.println("此内容会被写入 log.txt"); // 不再显示在控制台
```


#### 五、注意事项

1. **资源管理**  
   打印流包装其他流时,关闭打印流会自动关闭底层流:
   ```java
   // 错误示例:可能导致资源泄漏
   OutputStream fos = new FileOutputStream("file.txt");
   PrintStream ps = new PrintStream(fos);
   ps.close(); // 关闭 ps 会关闭 fos,但未处理异常

   // 正确示例:使用 try-with-resources
   try (PrintStream ps = new PrintStream(new FileOutputStream("file.txt"))) {
       ps.println("Data");
   } // 自动关闭 ps 和底层流
   ```

2. **编码问题**  
   - `PrintStream` 默认使用平台编码,可能导致乱码。  
   - 推荐使用 `PrintWriter` 并显式指定编码:  
     ```java
     PrintWriter writer = new PrintWriter(
         new OutputStreamWriter(new FileOutputStream("file.txt"), StandardCharsets.UTF_8),
         true // 自动刷新
     );
     ```

3. **性能考量**  
   频繁调用 `println()` 可能影响性能,大数据量输出时建议:  
   - 使用 `BufferedWriter` 包装 `PrintWriter`。  
   - 批量写入后手动调用 `flush()`。


#### 六、应用场景
- **日志输出**:将程序运行信息写入日志文件。  
- **数据导出**:生成 CSV、配置文件等文本格式。  
- **调试信息**:在控制台打印调试数据。  
- **网络编程**:通过 `Socket` 发送格式化数据。


#### 七、总结
打印流(`PrintStream`/`PrintWriter`)是 Java 中用于简化输出操作的核心工具,通过自动刷新、格式化输出和异常处理封装,显著提升了开发效率。选择 `PrintWriter` 而非 `PrintStream` 可更好地处理国际化和字符编码问题。

50.网络编程基础

  • 计算机网络:由两台或更多计算机组成的网络;
  • 互联网:连接网络的网络;
  • IP地址:计算机的网络接口(通常是网卡)在网络中的唯一标识;
  • 网关:负责连接多个网络,并在多个网络之间转发数据的计算机,通常是路由器或交换机;
  • 网络协议:互联网使用TCP/IP协议,它泛指互联网协议簇;
  • OSI: 七层模型
  • IP协议:一种分组交换传输协议;
  • TCP协议:一种面向连接,可靠传输的协议;
  • UDP协议:一种无连接,不可靠传输的协议。

51.common io

document

特性

Commons IO

Java NIO

API 风格

简单易用,面向流操作

复杂,面向缓冲区和通道

适用场景

简单文件操作、快速开发

高性能网络编程、大数据处理

性能

适用于中小数据量

适用于高并发、大文件

阻塞模式

基于 BIO(阻塞)

支持 NIO(非阻塞)

### Apache Commons IO 简要讲解

**Apache Commons IO** 是简化 Java IO 操作的工具库,提供以下核心功能:

1. **文件操作**  
   ```java
   FileUtils.readFileToString(file, "UTF-8");  // 读取文件为字符串
   FileUtils.copyDirectory(srcDir, destDir);  // 复制目录
   FileUtils.deleteQuietly(file);             // 安全删除文件
   ```

2. **流操作**  
   ```java
   IOUtils.copy(inputStream, outputStream);   // 复制流
   IOUtils.closeQuietly(stream);              // 安全关闭流
   ```

3. **路径处理**  
   ```java
   FilenameUtils.getExtension("file.txt");    // 获取扩展名
   FilenameUtils.normalize("path/../to");     // 规范化路径
   ```

4. **文件监听**  
   监控文件变化(创建、修改、删除)。

**优势**:减少样板代码,自动处理异常和资源关闭,跨平台兼容。  
**适用场景**:日常文件操作、数据导入导出、临时文件管理。  
**依赖**:  
```xml
<dependency>
    <groupId>org.apache.commons</groupId>

    <artifactId>commons-io</artifactId>

    <version>2.15.0</version>

</dependency>

```

Apache Commons IO 是简化 Java IO 操作的工具库,提供:

  1. 文件工具:读写、复制、删除文件 / 目录。
  1. 流工具:复制流、安全关闭、转换为字符串。
  1. 路径处理:规范化路径、获取扩展名。
  1. 文件监听:监控文件变化。

优势:减少样板代码,自动处理异常,跨平台兼容。
典型场景:文件导入导出、日志解析、临时文件管理。
依赖单模块,快速提升开发效率。

52.Java爬虫

维度

Java 爬虫

Python 爬虫

开发效率

较低(需编写较多样板代码)

极高(语法简洁,库丰富)

学习曲线

陡峭(需掌握 OOP、多线程等)

平缓(入门简单,适合快速原型)

性能

高(编译型语言,适合大规模数据)

低(解释型语言,IO 密集型更优)

并发模型

多线程(需手动管理线程池)

协程(asyncio、gevent)

社区生态

丰富(Jsoup、HttpClient、WebMagic)

超级丰富(Requests、Scrapy、Selenium)

适用场景

大规模分布式爬虫、企业级系统

小规模数据采集、快速验证

了解即可 学习成本太高 现阶段用python爬虫足够了 pyspider scrapy

53.正则表达式

正则表达式是用于文本匹配的模式工具,通过元字符组合定义规则:

  • 基础元字符.(任意字符)、\d(数字)、^(开头)、$(结尾)。
  • 限定符*(0 + 次)、+(1 + 次)、?(0/1 次)。
  • 字符类[abc](匹配其中之一)、[^0-9](非数字)。
  • 分组与引用()分组,\1引用首个分组。

应用场景:数据验证(邮箱、手机号)、文本提取 / 替换。需注意贪婪匹配与性能优化,可通过在线工具(如 Regex101)辅助调试。

### 正则表达式(Regular Expression)详解

#### 一、什么是正则表达式?
正则表达式是一种用于 **匹配、查找和替换文本** 的强大工具,通过定义特定模式(Pattern)来操作字符串。它广泛应用于文本处理、数据验证、爬虫、编辑器搜索替换等场景。


#### 二、核心元字符与语法

##### 1. 基础元字符
| 元字符 | 描述                     | 示例               | 匹配结果          |
|--------|--------------------------|--------------------|-------------------|
| `.`    | 匹配任意单个字符(除换行符) | `a.c`              | `abc`, `a1c`      |
| `\d`   | 匹配数字(等价于 `[0-9]`) | `\d\d`             | `12`, `99`        |
| `\w`   | 匹配单词字符(字母、数字、下划线) | `\w\w`         | `ab`, `a1`, `_1`  |
| `\s`   | 匹配空白字符(空格、制表符、换行符) | `a\sb`         | `a b`             |
| `^`    | 匹配字符串开头           | `^Hello`           | `Hello world`     |
| `$`    | 匹配字符串结尾           | `world$`           | `Hello world`     |


##### 2. 限定符(Quantifiers)
| 限定符 | 描述                     | 示例               | 匹配结果          |
|--------|--------------------------|--------------------|-------------------|
| `*`    | 匹配前面的元素 0 次或多次 | `a*b`              | `b`, `ab`, `aab`  |
| `+`    | 匹配前面的元素 1 次或多次 | `a+b`              | `ab`, `aab`       |
| `?`    | 匹配前面的元素 0 次或 1 次 | `colou?r`         | `color`, `colour` |
| `{n}`  | 匹配前面的元素恰好 n 次   | `a{3}`             | `aaa`             |
| `{n,}` | 匹配前面的元素至少 n 次   | `a{2,}`            | `aa`, `aaa`       |
| `{n,m}`| 匹配前面的元素 n 到 m 次  | `a{2,3}`           | `aa`, `aaa`       |


##### 3. 字符类(Character Classes)
| 语法     | 描述                     | 示例               |
|----------|--------------------------|--------------------|
| `[abc]`  | 匹配 a、b 或 c 中的任意一个字符 | `[aeiou]`         |
| `[^abc]` | 匹配除 a、b、c 之外的任意字符 | `[^0-9]`          |
| `[a-z]`  | 匹配指定范围内的任意字符   | `[A-Z0-9]`        |
| `[a-zA-Z]` | 匹配字母(大小写)       |                    |


##### 4. 分组与捕获
| 语法     | 描述                     | 示例               |
|----------|--------------------------|--------------------|
| `(...)`  | 分组,将多个元素视为一个整体 | `(ab)+`           |
| `\1`     | 反向引用第一个分组        | `(\d)\1`           | 匹配 `11`, `22`   |
| `(?<name>...)` | 命名分组               | `(?<year>\d{4})`  |


##### 5. 特殊字符
| 字符 | 描述                     |
|------|--------------------------|
| `\`  | 转义字符(如 `\.` 匹配点号) |
| `|`  | 或操作(如 `cat|dog`)   |
| `()` | 分组(用于限定范围或捕获) |


#### 三、在不同语言中的应用

##### 1. Python
```python
import re

# 匹配邮箱
text = "Contact me at test@example.com"
pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
matches = re.findall(pattern, text)
print(matches)  # 输出: ['test@example.com']

# 替换
new_text = re.sub(r'\d+', 'NUMBER', "I have 123 apples")
print(new_text)  # 输出: "I have NUMBER apples"
```

##### 2. Java
```java
import java.util.regex.*;

public class RegexExample {
    public static void main(String[] args) {
        String text = "Hello 123 World";
        Pattern pattern = Pattern.compile("\\d+");
        Matcher matcher = pattern.matcher(text);
        
        if (matcher.find()) {
            System.out.println(matcher.group());  // 输出: 123
        }
    }
}
```

##### 3. JavaScript
```javascript
const text = "Hello World";
const pattern = /World/;

console.log(pattern.test(text));  // 输出: true
console.log(text.replace(pattern, "JavaScript"));  // 输出: "Hello JavaScript"
```


#### 四、进阶技巧

##### 1. 贪婪匹配 vs 非贪婪匹配
- **贪婪匹配**(默认):尽可能多地匹配。  
  示例:`a.*c` 匹配 `abcdefc` 时会匹配整个字符串。

- **非贪婪匹配**(加 `?`):尽可能少地匹配。  
  示例:`a.*?c` 匹配 `abcdefc` 时会匹配 `abc`。


##### 2. 零宽断言(Lookaround)
| 语法       | 描述                     | 示例               |
|------------|--------------------------|--------------------|
| `(?=...)`  | 正向先行断言(后面必须匹配) | `\w+(?=\d)`       | 匹配 `a1` 中的 `a` |
| `(?!...)`  | 负向先行断言(后面不能匹配) | `\w+(?!\d)`       | 匹配 `ab` 中的 `ab` |
| `(?<=...)` | 正向后行断言(前面必须匹配) | `(?<=\$)\d+`      | 匹配 `$100` 中的 `100` |
| `(?<!...)` | 负向后行断言(前面不能匹配) | `(?<!\$)\d+`      | 匹配 `100` 但不匹配 `$100` 中的 `100` |


#### 五、常见应用场景

##### 1. 数据验证
- **邮箱**:`^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$`  
- **手机号**:`^1[3-9]\d{9}$`  
- **URL**:`^https?://\S+(\.\S+)+$`  

##### 2. 文本提取
- 提取 HTML 标签:`<[^>]+>`  
- 提取数字:`\d+`  

##### 3. 文本替换
- 替换敏感词:`(?i)fuck|shit` → `***`  


#### 六、性能注意事项
- **避免嵌套量词**:如 `(a+)*` 可能导致指数级回溯。  
- **优先使用具体字符类**:如 `[0-9]` 比 `\d` 更明确。  
- **编译正则表达式**:在循环中重复使用的正则表达式应预编译(如 Java 的 `Pattern.compile`)。


#### 七、工具推荐
- **在线测试**:[Regex101](https://regex101.com/)、[RegexPal](https://www.regexpal.com/)  
- **可视化工具**:[Regexper](https://regexper.com/)  
- **IDE 支持**:VS Code、IntelliJ IDEA 等内置正则表达式搜索。


#### 八、总结
正则表达式是处理文本的强大工具,但其语法复杂,需通过练习掌握。核心是理解 **元字符**、**限定符** 和 **分组** 的用法,以及在不同语言中的应用差异。合理使用正则表达式能显著提升文本处理效率,但需注意性能和可读性的平衡。

54.注解

Java 注解是代码元数据,提供配置信息而不直接影响程序逻辑。它通过 @interface 定义,可被编译器、框架或工具解析。内置注解如 @Override@Deprecated 等,自定义注解需配合元注解(@Retention@Target)指定作用范围。注解处理分编译时(如Lombok)、运行时(反射获取)和工具处理(如JUnit)。常见于框架配置(Spring)、数据验证(Hibernate)、ORM映射(JPA)。合理使用可提升开发效率,但需避免滥用。

### Java 注解(Annotation)详解

#### 一、注解是什么?
**注解** 是 Java 5 引入的一种元数据机制,用于为代码提供额外的信息(如配置、标记、约束等)。注解本身不直接影响代码逻辑,但可被编译器、框架或工具解析,实现诸如自动配置、代码生成、运行时行为调整等功能。

#### 二、注解的基本语法
1. **内置注解**  
   Java 提供的标准注解:  
   ```java
   @Override  // 标记方法重写父类方法
   @Deprecated  // 标记已过时的方法/类
   @SuppressWarnings("unchecked")  // 抑制编译器警告
   ```

2. **自定义注解**  
   使用 `@interface` 定义,可包含属性:  
   ```java
   import java.lang.annotation.*;

   @Retention(RetentionPolicy.RUNTIME)  // 注解保留到运行时
   @Target(ElementType.METHOD)  // 注解可用于方法
   public @interface MyAnnotation {
       String value() default "";  // 定义属性,默认值为空字符串
       int count() default 1;
   }
   ```

3. **元注解**  
   用于修饰注解的注解:  
   - `@Retention`:指定注解的保留策略(SOURCE/CLASS/RUNTIME)。  
   - `@Target`:指定注解可应用的目标类型(METHOD/TYPE/FIELD等)。  
   - `@Documented`:使注解在Javadoc中可见。  
   - `@Inherited`:允许子类继承父类的注解。

#### 三、注解的处理方式
注解的作用取决于其保留策略和处理方式:

1. **编译时处理**  
   注解被编译器读取,用于生成代码或进行静态检查。  
   示例:Lombok 通过 `@Data` 注解自动生成 getter/setter 方法。

2. **运行时反射处理**  
   通过反射机制在运行时获取注解信息,动态调整程序行为。  
   示例:Spring 通过 `@Autowired` 实现依赖注入:  
   ```java
   @Service
   public class UserService {
       @Autowired  // 运行时通过反射注入依赖
       private UserRepository repository;
   }
   ```

3. **工具处理**  
   第三方工具读取注解信息,生成配置文件或报告。  
   示例:JUnit 的 `@Test` 注解标记测试方法。

#### 四、注解的典型应用场景
1. **框架配置**  
   Spring 框架通过注解简化配置:  
   ```java
   @RestController
   @RequestMapping("/api")
   public class UserController {
       @GetMapping("/{id}")
       public User getUser(@PathVariable Long id) { ... }
   }
   ```

2. **单元测试**  
   JUnit 使用注解标记测试方法:  
   ```java
   @Test
   public void testAddition() {
       assertEquals(4, 2 + 2);
   }
   ```

3. **数据验证**  
   Hibernate Validator 通过注解实现参数校验:  
   ```java
   public class User {
       @NotNull(message = "姓名不能为空")
       private String name;
       
       @Email(message = "邮箱格式不正确")
       private String email;
   }
   ```

4. **ORM映射**  
   JPA 通过注解定义实体与数据库表的映射:  
   ```java
   @Entity
   @Table(name = "users")
   public class User {
       @Id
       @GeneratedValue(strategy = GenerationType.IDENTITY)
       private Long id;
   }
   ```

#### 五、注解与反射的结合
通过反射获取注解信息是注解最强大的应用方式:  
```java
import java.lang.reflect.Method;

public class AnnotationProcessor {
    public static void main(String[] args) throws Exception {
        Class<?> clazz = MyClass.class;
        Method method = clazz.getMethod("myMethod");
        
        // 检查方法是否有特定注解
        if (method.isAnnotationPresent(MyAnnotation.class)) {
            MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
            System.out.println("Value: " + annotation.value());
            System.out.println("Count: " + annotation.count());
        }
    }
}

@MyAnnotation(value = "test", count = 3)
class MyClass {
    public void myMethod() {}
}
```

#### 六、自定义注解实战示例
以下是一个自定义注解实现权限校验的示例:

1. **定义注解**  
   ```java
   @Retention(RetentionPolicy.RUNTIME)
   @Target(ElementType.METHOD)
   public @interface RequiresPermission {
       String value();  // 权限名称
   }
   ```

2. **注解处理器**  
   ```java
   public class SecurityInterceptor {
       public static boolean checkPermission(Method method) {
           if (method.isAnnotationPresent(RequiresPermission.class)) {
               RequiresPermission permission = method.getAnnotation(RequiresPermission.class);
               // 模拟权限校验逻辑
               return UserContext.getCurrentUser().hasPermission(permission.value());
           }
           return true;
       }
   }
   ```

3. **使用注解**  
   ```java
   public class UserController {
       @RequiresPermission("admin")
       public void deleteUser(Long userId) {
           // 删除用户逻辑
       }
   }
   ```

#### 七、注意事项
1. **性能开销**  
   反射读取注解会带来一定性能损耗,避免在高并发场景频繁使用。

2. **注解滥用**  
   避免过度使用注解导致代码可读性下降,复杂逻辑建议使用配置文件。

3. **兼容性**  
   自定义注解需考虑版本兼容性,新增属性时注意默认值。

#### 八、总结
Java 注解通过元数据增强代码表达力,结合反射机制可实现强大的动态功能。常见应用包括框架配置(如 Spring)、数据验证、测试框架等。理解注解的定义、处理方式及与反射的结合,是掌握 Java 高级编程的关键之一。

55.反射

### Java 反射机制详解

#### 一、反射是什么?
Java 反射(Reflection)是指在 **运行时** 动态获取类的信息(如属性、方法、构造器)并操作对象的能力。通过反射,程序可以在运行时:
- 检查类、方法、字段的信息。
- 创建对象、调用方法、修改属性。
- 动态加载类(如插件机制)。


#### 二、核心类与 API

##### 1. `Class` 类
`Class` 是反射的核心,每个类都有唯一的 `Class` 对象,获取方式:
```java
// 方式1:通过类名
Class<?> clazz = String.class;

// 方式2:通过对象实例
String str = "hello";
Class<?> clazz = str.getClass();

// 方式3:通过全类名(需处理 ClassNotFoundException)
Class<?> clazz = Class.forName("java.lang.String");
```

##### 2. `Field` 类(字段)
获取和操作类的属性:
```java
Class<?> clazz = Person.class;
Field field = clazz.getDeclaredField("name"); // 获取私有字段
field.setAccessible(true); // 打破访问权限限制
Person person = new Person();
field.set(person, "Alice"); // 设置属性值
String name = (String) field.get(person); // 获取属性值
```

##### 3. `Method` 类(方法)
获取和调用类的方法:
```java
Class<?> clazz = Person.class;
Method method = clazz.getMethod("sayHello", String.class); // 获取方法
Person person = new Person();
String result = (String) method.invoke(person, "World"); // 调用方法
```

##### 4. `Constructor` 类(构造器)
动态创建对象:
```java
Class<?> clazz = Person.class;
Constructor<?> constructor = clazz.getConstructor(String.class, int.class); // 获取构造器
Person person = (Person) constructor.newInstance("Bob", 25); // 创建对象
```


#### 三、反射的应用场景

##### 1. 框架开发
- **Spring**:通过反射实现依赖注入(如 `@Autowired`)。
- **MyBatis**:通过反射映射 SQL 查询结果到对象。

##### 2. 序列化与反序列化
- JSON 库(如 Jackson)通过反射将 JSON 字符串转为对象。

##### 3. 单元测试
- 通过反射访问私有方法或属性进行测试。

##### 4. 动态代理
- Java 的 `Proxy` 类通过反射实现 AOP(如事务管理)。


#### 四、反射的优缺点

##### 1. 优点
- **灵活性高**:运行时动态操作类,适合框架开发。
- **解耦**:减少代码间的硬依赖(如插件机制)。

##### 2. 缺点
- **性能开销大**:反射操作比直接调用慢(约 10-100 倍)。
- **破坏封装性**:可访问私有成员,违反面向对象原则。
- **安全性风险**:可能导致信息泄露或恶意操作。


#### 五、反射的性能优化
1. **缓存反射对象**:避免重复获取 `Class`、`Method` 等对象。
2. **使用 `setAccessible(true)`**:减少访问检查开销。
3. **结合 LambdaMetaFactory**:Java 8+ 可生成动态调用器提升性能。


#### 六、反射与泛型的关系
泛型在编译后会被擦除(Type Erasure),但通过反射仍可获取泛型信息:
```java
public class GenericClass<T> {
    private T value;
}

// 通过反射获取泛型类型
Class<?> clazz = GenericClass.class;
Type type = clazz.getGenericSuperclass();
ParameterizedType paramType = (ParameterizedType) type;
Type[] typeArgs = paramType.getActualTypeArguments(); // 获取泛型参数
```


#### 七、反射的安全性限制
- **模块系统限制**(Java 9+):需在 `module-info.java` 中声明 `opens` 模块。
- **安全管理器(SecurityManager)**:可能禁止某些反射操作。


#### 八、示例代码:动态调用方法
```java
import java.lang.reflect.Method;

public class ReflectionExample {
    public static void main(String[] args) throws Exception {
        // 获取 Class 对象
        Class<?> clazz = Class.forName("java.util.ArrayList");
        
        // 创建实例
        Object list = clazz.getDeclaredConstructor().newInstance();
        
        // 调用 add 方法
        Method addMethod = clazz.getMethod("add", Object.class);
        addMethod.invoke(list, "Hello");
        addMethod.invoke(list, "World");
        
        // 调用 size 方法
        Method sizeMethod = clazz.getMethod("size");
        int size = (int) sizeMethod.invoke(list);
        System.out.println("Size: " + size); // 输出: Size: 2
    }
}
```


#### 九、总结
Java 反射是一把“双刃剑”,它提供了强大的动态编程能力,但也带来了性能和安全风险。合理使用反射可以构建灵活的框架(如 Spring、Hibernate),但在性能敏感场景(如高频交易系统)应谨慎使用。理解反射机制是深入掌握 Java 高级编程的关键之一。

总结


### 核心技术快速回顾  
1. **Hutool工具库**  
   - 轻量级Java工具类库,封装字符串、集合、IO、加密等常用功能。  
   - 模块丰富(如hutool-core、hutool-http),支持简化开发流程,提升效率。  

2. **Socket与网络编程**  
   - **TCP**:面向连接,可靠传输,用ServerSocket/Socket实现,需处理粘包、多线程并发。  
   - **UDP**:无连接,不可靠,用DatagramSocket实现,适合实时场景(如游戏)。  
   - 对比HTTP:Socket是底层接口,需自定义协议;HTTP基于请求-响应,适合Web场景。  

3. **打印流(PrintStream/PrintWriter)**  
   - 简化输出操作,支持自动刷新、格式化输出(printf)。  
   - PrintStream处理字节流,PrintWriter处理字符流,需注意编码和资源关闭。  

4. **网络编程基础**  
   - 核心概念:IP地址、网关、TCP/IP协议、OSI七层模型。  
   - 协议对比:TCP可靠但延迟高,UDP反之;HTTP基于TCP,无状态。  

5. **Apache Commons IO**  
   - 简化IO操作,提供文件读写、流复制、路径处理等工具类。  
   - 对比Java NIO:易用性高,适合中小数据量;NIO适合高性能、大文件场景。  

6. **Java爬虫**  
   - 与Python对比:Java适合大规模分布式爬虫,开发效率低;Python库丰富,适合快速验证。  
   - 现阶段建议优先学习Python爬虫(如Scrapy)。  

7. **正则表达式**  
   - 元字符(如.、\d)、限定符(*、+)、分组(())构建匹配模式。  
   - 应用:数据验证(邮箱、手机号)、文本提取,需注意贪婪匹配与性能优化。  

8. **注解与反射**  
   - **注解**:元数据机制,分内置(@Override)、自定义(配合元注解),用于框架配置、数据验证。  
   - **反射**:运行时动态操作类,性能开销大,用于Spring依赖注入、序列化,需谨慎使用。