Java常用API全解:从Math到包装类,吃透开发必备工具
本文系统梳理Java开发中最常用的核心API,覆盖Math、System、Runtime、Object、包装类、正则表达式,结合实战案例、底层原理与避坑技巧,衔接前文面向对象进阶知识点,夯实Java工具类使用能力,后续将补充时间类相关内容。
一、Math类:数学运算工具类
Math类是Java中用于数学运算的工具类,位于java.lang包(无需导入),所有方法均为静态方法,直接通过Math.方法名()调用,无需创建对象,核心用于数值计算、取整、随机数等场景。Math类还包含多个常用静态常量(如圆周率π、自然常数e),满足日常数学运算需求。
1.1 核心常用方法(重点)
| 方法名 | 方法说明 | 示例 | 返回结果 |
|---|---|---|---|
| Math.abs(数值) | 取任意数值的绝对值(支持int、double等类型) | Math.abs(-10)、Math.abs(-3.14) | 10、3.14 |
| Math.ceil(double num) | 向上取整(返回大于等于参数的最小整数,结果为double类型) | Math.ceil(3.1)、Math.ceil(-3.1) | 4.0、-3.0 |
| Math.floor(double num) | 向下取整(返回小于等于参数的最大整数,结果为double类型) | Math.floor(3.9)、Math.floor(-3.9) | 3.0、-4.0 |
| Math.round(double num) | 四舍五入取整(返回long类型,小数部分≥0.5向上取整,否则向下取整) | Math.round(3.4)、Math.round(3.5) | 3、4 |
| Math.max(数值1, 数值2) | 取两个数值中的最大值(支持同类型数值对比) | Math.max(10, 20)、Math.max(3.14, 2.99) | 20、3.14 |
| Math.min(数值1, 数值2) | 取两个数值中的最小值(支持同类型数值对比) | Math.min(10, 20)、Math.min(3.14, 2.99) | 10、2.99 |
| Math.random() | 生成[0.0, 1.0)之间的随机double值(左闭右开区间) | Math.random() | 0.0~1.0之间的随机数(如0.356) |
| Math.pow(double a, double b) | 计算a的b次方(返回double类型) | Math.pow(2, 3)、Math.pow(4, 0.5) | 8.0、2.0 |
| Math.sqrt(double num) | 计算数值的平方根(返回double类型,参数需≥0) | Math.sqrt(16)、Math.sqrt(2) | 4.0、1.4142... |
1.2 常用静态常量
-
Math.PI:圆周率,值约为3.141592653589793
-
Math.E:自然常数,值约为2.718281828459045
1.3 实战案例:Math类综合使用
需求:生成1-100之间的随机整数,计算该整数的绝对值、平方根,以及与50的最大值、最小值,最后对结果四舍五入保留1位小数。
public class MathDemo {
public static void main(String[] args) {
// 1. 生成1-100之间的随机整数(Math.random()生成[0,1),扩大100倍后取整)
int randomNum = (int) (Math.random() * 100 + 1);
System.out.println("生成的随机整数:" + randomNum);
// 2. 计算绝对值(此处演示,随机数已为正数)
int absNum = Math.abs(randomNum);
System.out.println("随机数的绝对值:" + absNum);
// 3. 计算平方根(转换为double类型)
double sqrtNum = Math.sqrt(randomNum);
System.out.println("随机数的平方根:" + sqrtNum);
// 4. 计算与50的最大值、最小值
int maxNum = Math.max(randomNum, 50);
int minNum = Math.min(randomNum, 50);
System.out.println("与50的最大值:" + maxNum);
System.out.println("与50的最小值:" + minNum);
// 5. 四舍五入保留1位小数(先扩大10倍,四舍五入,再缩小10倍)
double roundNum = Math.round(sqrtNum * 10) / 10.0;
System.out.println("平方根四舍五入保留1位小数:" + roundNum);
// 6. 演示圆周率和自然常数的使用
System.out.println("圆周率π:" + Math.PI);
System.out.println("自然常数e:" + Math.E);
}
}
1.4 避坑点
-
Math.ceil()、Math.floor()返回值是double类型,而非int类型,若需int类型,需手动强制转换(如(int)Math.ceil(3.1) → 4);
-
Math.random()生成的是[0.0, 1.0)的左闭右开区间,生成1-n之间的随机整数,公式为:(int)(Math.random() * n + 1);
-
Math.round()参数为double时,返回long类型,若需int类型,需强制转换,避免类型转换异常。
二、System类:系统相关工具类
System类位于java.lang包(无需导入),所有成员均为静态成员(静态方法、静态变量),核心用于获取系统信息、操作输入输出流、管理垃圾回收、获取当前时间等,是Java开发中高频使用的系统级工具类。
2.1 核心常用方法与变量
| 方法/变量名 | 说明 | 示例 |
|---|---|---|
| System.out | 静态变量,对应标准输出流(控制台打印),常用println()、print()方法 | System.out.println("Hello Java") |
| System.in | 静态变量,对应标准输入流(从控制台读取输入),需配合Scanner使用 | Scanner sc = new Scanner(System.in) |
| System.err | 静态变量,对应标准错误输出流(打印错误信息,通常为红色) | System.err.println("错误信息") |
| System.currentTimeMillis() | 返回当前系统时间戳(毫秒级),从1970-01-01 00:00:00 UTC开始计算,常用于计算程序执行时间 | System.currentTimeMillis() |
| System.nanoTime() | 返回当前系统时间戳(纳秒级),精度比currentTimeMillis()更高,适合计算短时间任务的执行耗时 | System.nanoTime() |
| System.gc() | 建议JVM执行垃圾回收(仅为建议,JVM不一定立即执行),回收未被引用的对象,释放内存 | System.gc() |
| System.exit(int status) | 终止当前Java虚拟机,status为0表示正常退出,非0表示异常退出 | System.exit(0) |
| System.arraycopy(源数组, 源起始索引, 目标数组, 目标起始索引, 复制长度) | 复制数组元素,效率比for循环复制更高,常用于数组拷贝场景 | System.arraycopy(arr1, 0, arr2, 0, 3) |
2.2 实战案例:System类综合使用
需求:计算一段代码的执行耗时,拷贝数组,演示垃圾回收和系统退出的使用。
public class SystemDemo {
public static void main(String[] args) {
// 1. 计算代码执行耗时(毫秒级)
long start = System.currentTimeMillis();
// 模拟耗时操作:循环10000次
for (int i = 0; i < 10000; i++) {
Math.random();
}
long end = System.currentTimeMillis();
System.out.println("循环执行耗时:" + (end - start) + "毫秒");
// 2. 数组拷贝(使用System.arraycopy)
int[] arr1 = {1, 2, 3, 4, 5};
int[] arr2 = new int[5];
// 拷贝arr1的前3个元素,从索引0开始,拷贝到arr2的索引0位置
System.arraycopy(arr1, 0, arr2, 0, 3);
System.out.print("拷贝后的arr2:");
for (int num : arr2) {
System.out.print(num + " "); // 输出:1 2 3 0 0
}
System.out.println();
// 3. 演示垃圾回收(仅建议,JVM不一定立即执行)
// 创建一个临时对象,使用后赋值为null,变为垃圾对象
Object obj = new Object();
obj = null;
System.out.println("建议JVM执行垃圾回收");
System.gc();
// 4. 演示系统退出(注释后可正常执行后续代码,取消注释则终止程序)
// System.out.println("程序即将退出");
// System.exit(0);
// System.out.println("这句话不会执行");
}
}
2.3 避坑点
-
System.currentTimeMillis()返回的是毫秒级时间戳,时区为UTC,若需转换为本地时间,需结合时间类(如Date、LocalDateTime)使用;
-
System.gc()仅为“建议”JVM执行垃圾回收,不能强制JVM立即回收垃圾,垃圾回收的时机由JVM自主决定;
-
System.arraycopy()拷贝时,需注意源数组、目标数组的长度和索引,避免数组越界异常(ArrayIndexOutOfBoundsException);
-
System.exit(0)会直接终止虚拟机,后续代码不会执行,需谨慎使用(如在try-catch的finally中使用,会导致finally中后续代码无法执行)。
三、Runtime类:运行时环境工具类
Runtime类位于java.lang包(无需导入),用于获取当前Java虚拟机的运行时环境信息,如内存使用情况、处理器数量,还能执行系统命令、管理虚拟机进程。Runtime类是单例模式,不能通过new创建对象,需通过Runtime.getRuntime()方法获取唯一实例。
3.1 核心常用方法
| 方法名 | 说明 | 示例 |
|---|---|---|
| Runtime.getRuntime() | 获取Runtime类的唯一实例(单例模式) | Runtime runtime = Runtime.getRuntime() |
| totalMemory() | 返回JVM的总内存大小(字节),即JVM初始分配的内存总量 | runtime.totalMemory() |
| freeMemory() | 返回JVM当前的空闲内存大小(字节) | runtime.freeMemory() |
| maxMemory() | 返回JVM能获取的最大内存大小(字节),超出该大小会抛出内存溢出异常(OutOfMemoryError) | runtime.maxMemory() |
| availableProcessors() | 返回当前设备的处理器核心数,常用于多线程编程中设置线程数 | runtime.availableProcessors() |
| exec(String command) | 执行系统命令(如打开记事本、查看文件列表),返回Process对象,需处理异常 | runtime.exec("notepad.exe")(Windows打开记事本) |
| gc() | 与System.gc()功能一致,建议JVM执行垃圾回收 | runtime.gc() |
3.2 实战案例:Runtime类综合使用
需求:获取JVM内存信息(总内存、空闲内存、最大内存),获取处理器核心数,执行系统命令(Windows打开记事本)。
import java.io.IOException;
public class RuntimeDemo {
public static void main(String[] args) {
// 1. 获取Runtime类的唯一实例
Runtime runtime = Runtime.getRuntime();
// 2. 获取JVM内存信息(转换为MB,1MB = 1024*1024字节)
long totalMemory = runtime.totalMemory() / (1024 * 1024);
long freeMemory = runtime.freeMemory() / (1024 * 1024);
long maxMemory = runtime.maxMemory() / (1024 * 1024);
System.out.println("JVM总内存:" + totalMemory + "MB");
System.out.println("JVM空闲内存:" + freeMemory + "MB");
System.out.println("JVM最大内存:" + maxMemory + "MB");
System.out.println("当前设备处理器核心数:" + runtime.availableProcessors());
// 3. 执行系统命令(Windows打开记事本,Linux/macOS需修改命令)
try {
System.out.println("打开记事本...");
runtime.exec("notepad.exe");
} catch (IOException e) {
e.printStackTrace();
}
// 4. 建议垃圾回收,查看回收后的空闲内存
runtime.gc();
long freeMemoryAfterGc = runtime.freeMemory() / (1024 * 1024);
System.out.println("垃圾回收后的空闲内存:" + freeMemoryAfterGc + "MB");
}
}
3.3 避坑点
-
Runtime类是单例模式,只能通过getRuntime()方法获取实例,不能new创建,否则编译报错;
-
exec()方法执行系统命令时,不同操作系统的命令不同(如Windows打开记事本是notepad.exe,macOS是open -a TextEdit),需注意跨平台兼容性;
-
exec()方法会抛出IOException异常,必须处理(try-catch或throws);
-
JVM内存信息(totalMemory、freeMemory等)是动态变化的,每次获取的结果可能不同,仅作参考。
四、Object类:所有类的父类
Object类位于java.lang包(无需导入),是Java中所有类的直接或间接父类(若一个类没有显式继承其他类,默认继承Object类)。Object类定义了所有对象都具备的核心方法,子类可根据需求重写这些方法,实现个性化功能。
4.1 核心常用方法(重点,必须掌握)
4.1.1 equals(Object obj):判断两个对象是否相等
默认实现:Object类的equals()方法,本质是比较两个对象的内存地址(与==效果一致),即return this == obj;。
重写场景:当需要判断两个对象的“内容相等”(而非内存地址相等)时,需重写equals()方法(如String类、包装类已重写)。
重写原则(必须遵守):
-
自反性:obj.equals(obj) → true;
-
对称性:若a.equals(b)为true,则b.equals(a)也为true;
-
传递性:若a.equals(b)为true,b.equals(c)为true,则a.equals(c)也为true;
-
一致性:多次调用obj.equals(obj2),结果始终一致(对象内容未修改的情况下);
-
非空性:obj.equals(null) → false。
4.1.2 hashCode():返回对象的哈希值
默认实现:Object类的hashCode()方法,返回对象的内存地址对应的整数(不同对象的哈希值一般不同)。
核心规则:equals()方法返回true的两个对象,hashCode()必须返回相同的值;equals()返回false的两个对象,hashCode()可以返回相同的值(但不推荐,会降低哈希表效率)。
注意:重写equals()方法时,必须同时重写hashCode()方法,否则会违反上述规则,导致HashSet、HashMap等集合无法正常工作。
4.1.3 toString():返回对象的字符串表示
默认实现:Object类的toString()方法,返回格式为:类名@哈希值的十六进制(如com.xxx.ObjectDemo@1b6d3586),无实际意义。
重写场景:为了更直观地查看对象的属性信息,通常会重写toString()方法,返回对象的属性值(如自定义实体类)。
4.1.4 其他常用方法
-
getClass():返回对象的运行时类(Class对象),常用于反射编程,无法重写;
-
notify():唤醒当前对象的等待线程(多线程相关);
-
notifyAll():唤醒当前对象的所有等待线程(多线程相关);
-
wait():让当前线程进入等待状态(多线程相关),需在同步代码块中使用。
4.2 实战案例:重写Object类的核心方法
需求:自定义Student类,重写equals()、hashCode()、toString()方法,实现对象内容对比和直观打印。
import java.util.Objects;
// 自定义Student类,默认继承Object类
class Student {
private String name;
private int age;
private String studentId;
// 构造方法
public Student(String name, int age, String studentId) {
this.name = name;
this.age = age;
this.studentId = studentId;
}
// 重写toString()方法,返回对象属性信息
@Override
public String toString() {
return "Student{name='" + name + "', age=" + age + ", studentId='" + studentId + "'}";
}
// 重写equals()方法,按姓名+学号判断对象是否相等
@Override
public boolean equals(Object o) {
if (this == o) return true; // 内存地址相同,直接返回true
if (o == null || getClass() != o.getClass()) return false; // 非同一类型,返回false
Student student = (Student) o; // 强制转换
// 比较核心属性(姓名、学号),年龄可根据需求决定是否参与比较
return age == student.age && Objects.equals(name, student.name) && Objects.equals(studentId, student.studentId);
}
// 重写hashCode()方法,与equals()方法保持一致
@Override
public int hashCode() {
return Objects.hash(name, age, studentId);
}
}
// 测试类
public class ObjectDemo {
public static void main(String[] args) {
// 创建两个内容相同的Student对象
Student s1 = new Student("张三", 20, "2024001");
Student s2 = new Student("张三", 20, "2024001");
Student s3 = new Student("李四", 21, "2024002");
// 测试toString()方法
System.out.println(s1); // 输出重写后的字符串:Student{name='张三', age=20, studentId='2024001'}
System.out.println(s2);
// 测试equals()方法
System.out.println("s1.equals(s2):" + s1.equals(s2)); // true(内容相等)
System.out.println("s1.equals(s3):" + s1.equals(s3)); // false(内容不同)
System.out.println("s1.equals(null):" + s1.equals(null)); // false(非空性)
// 测试hashCode()方法
System.out.println("s1的hashCode:" + s1.hashCode());
System.out.println("s2的hashCode:" + s2.hashCode()); // 与s1相同
System.out.println("s3的hashCode:" + s3.hashCode()); // 与s1不同
// 测试getClass()方法
System.out.println("s1的运行时类:" + s1.getClass()); // class com.xxx.Student
}
}
4.3 避坑点
-
equals()与==的区别:==比较的是对象的内存地址(基本数据类型比较的是值),equals()默认比较内存地址,重写后可比较内容;
-
重写equals()必须重写hashCode(),否则会导致HashSet中无法去重(HashSet先通过hashCode()判断,再通过equals()判断);
-
toString()方法重写后,打印对象时会自动调用,无需手动调用(如System.out.println(s1),本质是调用s1.toString());
-
getClass()方法无法重写,若需判断对象类型,也可使用instanceof关键字(如s1 instanceof Student)。
五、包装类:基本数据类型的封装类
Java中基本数据类型(byte、short、int、long、float、double、char、boolean)不是对象,无法直接使用面向对象的特性(如调用方法、存储到集合中)。包装类是对基本数据类型的封装,将基本数据类型转换为对象,实现面向对象编程,同时提供了大量常用方法。
包装类与基本数据类型的对应关系(8种):
| 基本数据类型 | 包装类(java.lang包,无需导入) |
|---|---|
| byte | Byte |
| short | Short |
| int | Integer |
| long | Long |
| float | Float |
| double | Double |
| char | Character |
| boolean | Boolean |
5.1 核心特性:自动装箱与自动拆箱
JDK 1.5+新增特性,无需手动转换基本数据类型与包装类,JVM自动完成转换,简化代码。
-
自动装箱:基本数据类型 → 包装类(如int → Integer);
-
自动拆箱:包装类 → 基本数据类型(如Integer → int)。
public class WrapperDemo1 {
public static void main(String[] args) {
// 自动装箱:int → Integer
Integer num1 = 10; // 等价于:Integer num1 = Integer.valueOf(10);
// 自动拆箱:Integer → int
int num2 = num1; // 等价于:int num2 = num1.intValue();
// 包装类对象可以为null(基本数据类型不能为null)
Integer num3 = null;
// int num4 = num3; // 报错:NullPointerException(空指针异常)
// 包装类与基本数据类型比较(自动拆箱)
System.out.println(num1 == 10); // true
System.out.println(num1.equals(10)); // true(equals()重写,比较值)
}
}
5.2 核心常用方法(以Integer、Character为例)
5.2.1 Integer类常用方法
| 方法名 | 说明 | 示例 |
|---|---|---|
| Integer.valueOf(int i) | 将int类型转换为Integer对象(自动装箱底层调用此方法) | Integer.valueOf(10) → 10 |
| Integer.parseInt(String s) | 将字符串转换为int类型(字符串必须是纯数字,否则报错) | Integer.parseInt("123") → 123 |
| intValue() | 将Integer对象转换为int类型(自动拆箱底层调用此方法) | new Integer(10).intValue() → 10 |
| toString() | 将Integer对象转换为字符串 | new Integer(10).toString() → "10" |
| max(int a, int b) | 取两个int值的最大值(静态方法) | Integer.max(10, 20) → 20 |
| min(int a, int b) | 取两个int值的最小值(静态方法) | Integer.min(10, 20) → 10 |
5.2.2 Character类常用方法
| 方法名 | 说明 | 示例 |
|---|---|---|
| Character.valueOf(char c) | 将char类型转换为Character对象 | Character.valueOf('a') → 'a' |
| charValue() | 将Character对象转换为char类型 | new Character('a').charValue() → 'a' |
| isLetter(char c) | 判断字符是否为字母(大小写均可) | Character.isLetter('A') → true;Character.isLetter('1') → false |
| isDigit(char c) | 判断字符是否为数字 | Character.isDigit('5') → true;Character.isDigit('a') → false |
| isUpperCase(char c) | 判断字符是否为大写字母 | Character.isUpperCase('A') → true;Character.isUpperCase('a') → false |
| isLowerCase(char c) | 判断字符是否为小写字母 | Character.isLowerCase('a') → true;Character.isLowerCase('A') → false |
| toUpperCase(char c) | 将字符转换为大写 | Character.toUpperCase('a') → 'A' |
| toLowerCase(char c) | 将字符转换为小写 | Character.toLowerCase('A') → 'a' |
5.3 实战案例:包装类综合使用
需求:将字符串类型的数字转换为int类型,判断字符类型,实现数字与字符串的转换,演示自动装箱与拆箱。
public class WrapperDemo2 {
public static void main(String[] args) {
// 1. 字符串转int(常用场景:接收控制台输入的数字)
String strNum = "12345";
int num = Integer.parseInt(strNum);
System.out.println("字符串转int:" + num);
// 错误示例:字符串不是纯数字,转换报错
// String str = "123a";
// int errorNum = Integer.parseInt(str); // 报错:NumberFormatException
// 2. int转字符串
int num2 = 678;
String strNum2 = Integer.toString(num2);
System.out.println("int转字符串:" + strNum2 + ",类型:" + strNum2.getClass().getSimpleName());
// 3. 字符类型判断
char c1 = 'A';
char c2 = '5';
char c3 = 'b';
System.out.println(c1 + "是字母?" + Character.isLetter(c1)); // true
System.out.println(c2 + "是数字?" + Character.isDigit(c2)); // true
System.out.println(c3 + "是小写字母?" + Character.isLowerCase(c3)); // true
System.out.println("将" + c1 + "转为小写:" + Character.toLowerCase(c1)); // 'a'
// 4. 自动装箱与拆箱的实际应用(存储到集合中)
java.util.List<Integer> list = new java.util.ArrayList<>();
list.add(10); // 自动装箱:int → Integer
list.add(20);
list.add(30);
// 遍历集合,自动拆箱:Integer → int
for (int n : list) {
System.out.print(n + " "); // 输出:10 20 30
}
}
}
5.4 避坑点
-
包装类对象可以为null,基本数据类型不能为null,使用包装类时需注意空指针异常(如Integer num = null; int n = num; 会报错);
-
Integer.parseInt(String s)方法,字符串必须是纯数字(可含正负号),否则会抛出NumberFormatException(数字格式异常);
-
Integer缓存机制:Integer.valueOf(int i)方法,对-128~127之间的整数进行缓存,多次调用返回同一个对象(超出范围则创建新对象);
-
包装类的equals()方法已重写,比较的是值,而非内存地址;==比较的是内存地址(自动拆箱时除外)。
六、正则表达式:字符串匹配工具
正则表达式(Regular Expression)是一种用于匹配字符串的模式,可快速实现字符串的校验、查找、替换、分割等操作,Java中通过java.util.regex包下的Pattern类和Matcher类实现正则表达式的使用,是字符串处理的核心工具。
6.1 核心正则表达式语法(常用)
正则表达式由普通字符(如a、1、@)和特殊字符(元字符)组成,以下是开发中最常用的语法:
| 元字符 | 说明 | 示例 |
|---|---|---|
| . | 匹配任意单个字符(除了换行符\n) | "a.b"可匹配"aab"、"acb"、"a1b" |
| * | 匹配前面的字符0次或多次 | "a*b"可匹配"b"、"ab"、"aab"、"aaab" |
| + | 匹配前面的字符1次或多次 | "a+b"可匹配"ab"、"aab"、"aaab"(不能匹配"b") |
| ? | 匹配前面的字符0次或1次 | "a?b"可匹配"b"、"ab"(不能匹配"aab") |
| {n} | 匹配前面的字符恰好n次 | "a{3}b"可匹配"aaab"(不能匹配"aab"、"aaaab") |
| {n,} | 匹配前面的字符至少n次 | "a{2,}b"可匹配"aab"、"aaab"、"aaaab" |
| {n,m} | 匹配前面的字符n~m次(包含n和m) | "a{2,3}b"可匹配"aab"、"aaab" |
| [] | 匹配括号内的任意一个字符 | "[abc]"可匹配"a"、"b"、"c";"[0-9]"可匹配任意数字 |
| [^] | 匹配括号内以外的任意一个字符 | "[^abc]"可匹配除"a"、"b"、"c"以外的任意字符 |
| 匹配字符串的开头 | "^abc"可匹配"abc123"(不能匹配"123abc") | |
| $ | 匹配字符串的结尾 | "abc$"可匹配"123abc"(不能匹配"abc123") |
| \d | 匹配任意数字(等价于[0-9]) | "a\d"可匹配"a1"、"a2"、"a3" |
| \D | 匹配任意非数字(等价于[^0-9]) | "a\D"可匹配"aa"、"ab"、"a@" |
| \w | 匹配字母、数字、下划线(等价于[a-zA-Z0-9_]) | "a\w"可匹配"a1"、"aa"、"a_" |
| \W | 匹配非字母、非数字、非下划线(等价于[^a-zA-Z0-9_]) | "a\W"可匹配"a@"、"a#"、"a " |
| \s | 匹配任意空白字符(空格、制表符、换行符等) | "a\s"可匹配"a "、"a\t"(制表符) |
| \S | 匹配任意非空白字符 | "a\S"可匹配"a1"、"aa"、"a@" |
6.2 开发中高频正则表达式模板
-
手机号校验:
^1[3-9]\d{9}$(11位,开头为13-9,后面跟9位数字); -
邮箱校验:
^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$(支持字母、数字、下划线、中划线,支持多级域名); -
身份证号校验(18位):
^\d{17}[\dXx]$(前17位为数字,最后一位为数字或X/x); -
用户名校验(4-16位,支持字母、数字、下划线,不能以数字开头):
^[a-zA-Z_]\w{3,15}$; -
密码校验(8-20位,包含大小写字母、数字、特殊符号至少两种):
^(?![a-zA-Z]+$)(?![0-9]+$)(?![^a-zA-Z0-9]+$).{8,20}$; -
纯数字校验(任意长度正整数):
^\d+$; -
中文校验(仅含中文,任意长度):
^[\u4e00-\u9fa5]+$; -
URL校验(支持http/https):
^(https?://)?([\da-z.-]+)\.([a-z.]{2,6})([/\w.-]*)*(/?)$; -
日期校验(yyyy-MM-dd格式):
^\d{4}-\d{2}-\d{2}$。
6.3 Java中正则表达式的使用(Pattern与Matcher类)
Java中使用正则表达式,核心依赖java.util.regex.Pattern和java.util.regex.Matcher两个类,无需手动导入(JDK自带),常用使用步骤:1. 编译正则表达式(Pattern.compile());2. 创建匹配器(pattern.matcher(目标字符串));3. 执行匹配、查找、替换等操作。
6.3.1 核心方法(重点)
| 类与方法 | 说明 | 示例 |
|---|---|---|
| Pattern.compile(String regex) | 编译正则表达式,返回Pattern对象(线程安全,可复用) | Pattern pattern = Pattern.compile("^1[3-9]\d{9}$") |
| pattern.matcher(String input) | 创建匹配器,关联目标字符串,返回Matcher对象 | Matcher matcher = pattern.matcher("13800138000") |
| matcher.matches() | 判断整个目标字符串是否完全匹配正则表达式(常用校验场景) | matcher.matches() → true/false |
| matcher.find() | 查找目标字符串中是否包含匹配正则的子串(可多次调用) | while(matcher.find()) { ... } |
| matcher.replaceAll(String replacement) | 将所有匹配正则的子串替换为指定字符串 | matcher.replaceAll("***") |
| Pattern.matches(String regex, String input) | 静态方法,简化写法,直接判断字符串是否匹配正则(无需创建Pattern和Matcher) | Pattern.matches("^\d+$", "123") → true |
6.4 实战案例:正则表达式综合使用
需求:实现常见字符串校验(手机号、邮箱、身份证号)、查找字符串中的数字、替换敏感字符(如手机号中间4位打码)。
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexDemo {
public static void main(String[] args) {
// 1. 字符串校验(手机号、邮箱、身份证号)
String phone = "13800138000";
String email = "test_123@163.com";
String idCard = "11010119900307123X";
// 手机号校验
boolean isPhone = Pattern.matches("^1[3-9]\\d{9}$", phone);
// 邮箱校验
boolean isEmail = Pattern.matches("^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$", email);
// 身份证号校验(18位)
boolean isIdCard = Pattern.matches("^\\d{17}[\\dXx]$", idCard);
System.out.println("手机号校验:" + isPhone); // true
System.out.println("邮箱校验:" + isEmail); // true
System.out.println("身份证号校验:" + isIdCard); // true
// 2. 查找字符串中的所有数字
String str = "Java123编程456,正则789实战";
Pattern numPattern = Pattern.compile("\\d+");
Matcher numMatcher = numPattern.matcher(str);
System.out.print("字符串中的数字:");
while (numMatcher.find()) {
// group()方法获取匹配到的子串
System.out.print(numMatcher.group() + " "); // 输出:123 456 789
}
System.out.println();
// 3. 替换敏感字符(手机号中间4位打码)
String phone2 = "13912345678";
Pattern phonePattern = Pattern.compile("(^1[3-9]\\d{2})(\\d{4})(\\d{4})$");
Matcher phoneMatcher = phonePattern.matcher(phone2);
// 分组替换,$1表示第一个分组,$2第二个分组,$3第三个分组
String maskedPhone = phoneMatcher.replaceAll("$1****$3");
System.out.println("打码后的手机号:" + maskedPhone); // 输出:139****5678
// 4. 分割字符串(按任意空白字符分割)
String str2 = "Java 正则 实战 2024";
String[] arr = str2.split("\\s+");
System.out.print("分割后的字符串数组:");
for (String s : arr) {
System.out.print(s + "|"); // 输出:Java|正则|实战|2024|
}
}
}
6.5 避坑点
-
正则表达式中的反斜杠
\,在Java字符串中需转义,即写为\\(如\d在Java中需写为\\d),否则会被识别为转义字符报错; -
matches()方法是“全匹配”,必须整个字符串符合正则才返回true,若需“部分匹配”(包含子串),需使用find()方法;
-
Pattern对象线程安全,可复用(如多次校验手机号,可只编译一次Pattern),Matcher对象非线程安全,不可跨线程使用;