Java API
一、字符串类
Java API(Application Programming Interface)是 Java 提供的一套预先定义的类和接口,用于简化开发人员的编程工作,涵盖了字符串处理、集合操作、IO 流、网络编程等众多领域。其中,字符串类是 Java 中最常用的 API 之一,主要包括String、StringBuffer和StringBuilder三个核心类,它们在字符串的创建、修改和操作中扮演着不同的角色。
1.String类的初始化
String类用于表示不可变的字符序列(一旦创建,字符串的内容就无法修改),其初始化主要有两种常见方式:
(1)直接赋值方式
通过字面量直接赋值,字符串会被加入字符串常量池(方法区中的一块内存区域,用于缓存字符串字面量,避免重复创建),实现复用。
// 直接赋值,s1指向常量池中的"Hello Java"
String s1 = "Hello Java";
// s2复用常量池中的"Hello Java",与s1指向同一对象
String s2 = "Hello Java";
System.out.println(s1 == s2); // 输出true(引用地址相同)
(2)通过 new 关键字创建
通过new String()构造方法创建的字符串对象,会在堆内存中新建对象,即使内容相同,也会创建新的实例(常量池若不存在该字面量,会先在常量池创建,再在堆中创建对象指向常量池的字面量)。
// 堆中创建新对象,s3指向堆地址,常量池同时存在"Hello Java"
String s3 = new String("Hello Java");
// 堆中创建另一个新对象,s4指向新的堆地址
String s4 = new String("Hello Java");
System.out.println(s3 == s4); // 输出false(引用地址不同)
System.out.println(s3.equals(s4)); // 输出true(内容相同)
(3)其他构造方法
String还提供了基于字符数组、字节数组等的构造方法(了解即可):
// 基于字符数组初始化
char[] chs = {'J', 'a', 'v', 'a'};
String s5 = new String(chs); // 结果为"Java"
// 基于字节数组初始化(指定编码)
byte[] bytes = "Java".getBytes(StandardCharsets.UTF_8);
String s6 = new String(bytes, StandardCharsets.UTF_8); // 结果为"Java"
2.String类的常见操作
String类提供了丰富的方法用于字符串的查询、比较、截取、替换等操作,以下是最常用的方法:
(1)字符串长度与空判断
int length():返回字符串的字符个数。boolean isEmpty():判断字符串是否为空(长度为 0)。
String s = "Java API";
System.out.println(s.length()); // 输出7
System.out.println(s.isEmpty()); // 输出false
(2)字符与子串查询
char charAt(int index):获取指定索引位置的字符(索引从 0 开始)。int indexOf(String str):返回子串第一次出现的索引,不存在则返回 - 1。int lastIndexOf(String str):返回子串最后一次出现的索引。
String s = "Hello Java";
System.out.println(s.charAt(6)); // 输出'J'
System.out.println(s.indexOf("Java")); // 输出6
System.out.println(s.lastIndexOf("o")); // 输出4
(3)字符串比较
boolean equals(Object obj):比较字符串内容是否相同(区分大小写)。boolean equalsIgnoreCase(String anotherString):忽略大小写比较内容。int compareTo(String anotherString):按字典序比较(返回差值,0 表示相等)。
String s1 = "Java";
String s2 = "java";
System.out.println(s1.equals(s2)); // 输出false
System.out.println(s1.equalsIgnoreCase(s2)); // 输出true
System.out.println(s1.compareTo(s2)); // 输出-32('J'与'j'的ASCII差值)
(4)字符串截取与拆分
String substring(int beginIndex):从指定索引截取到字符串末尾。String substring(int beginIndex, int endIndex):截取 [beginIndex, endIndex) 区间的子串(左闭右开)。String[] split(String regex):按指定正则表达式拆分字符串为数组。
String s = "Hello,Java,API";
System.out.println(s.substring(6)); // 输出"Java,API"
System.out.println(s.substring(6, 10)); // 输出"Java"
String[] arr = s.split(","); // 结果为["Hello", "Java", "API"]
(5)字符串替换与去除空格
String replace(CharSequence target, CharSequence replacement):替换指定子串。String replaceAll(String regex, String replacement):按正则表达式替换。String trim():去除字符串首尾的空白字符(JDK11 + 提供strip(),支持全角空格)。
String s = " Hello Java ";
System.out.println(s.replace("Java", "API")); // 输出" Hello API "
System.out.println(s.trim()); // 输出"Hello Java"
(6)字符串转换
String toUpperCase():转换为大写。String toLowerCase():转换为小写。static String valueOf(Object obj):将任意类型转换为字符串(常用作字符串拼接)。
String s = "Java API";
System.out.println(s.toUpperCase()); // 输出"JAVA API"
System.out.println(String.valueOf(123)); // 输出"123"
3.StringBuffer类
StringBuffer是线程安全的可变字符序列,用于频繁修改字符串的场景(如多线程环境下的字符串拼接),其对象的内容可以通过方法修改,不会创建新的对象。
(1)初始化
// 空构造,初始容量为16
StringBuffer sb1 = new StringBuffer();
// 指定初始字符串
StringBuffer sb2 = new StringBuffer("Java");
// 指定初始容量
StringBuffer sb3 = new StringBuffer(20);
(2)核心方法(支持链式调用)
append(任意类型):在字符串末尾追加内容。insert(int offset, 任意类型):在指定位置插入内容。delete(int start, int end):删除 [start, end) 区间的字符。replace(int start, int end, String str):替换指定区间的字符。reverse():反转字符串。toString():转换为 String 类型。
StringBuffer sb = new StringBuffer("Hello");
sb.append(" Java") // 变为"Hello Java"
.insert(5, ",") // 变为"Hello, Java"
.reverse(); // 变为"avaJ ,olleH"
System.out.println(sb.toString()); // 输出最终结果
4.StringBuilder类
StringBuilder是非线程安全的可变字符序列,功能与StringBuffer几乎完全一致,但去掉了方法的同步锁,因此性能更高,是单线程环境下修改字符串的首选。
与StringBuffer用法完全一致:
StringBuilder sb = new StringBuilder("Java");
sb.append(" API")
.insert(4, ",");
System.out.println(sb.toString()); // 输出"Java, API"
与 StringBuffer 的区别:
| 特性 | StringBuffer | StringBuilder |
|---|---|---|
| 线程安全 | 线程安全(同步) | 非线程安全(非同步) |
| 性能 | 较低(同步开销) | 较高(无同步开销) |
| 适用场景 | 多线程环境 | 单线程环境 |
二、System类与Runtime类
在 Java API 中,System类和Runtime类是与系统环境、虚拟机运行状态密切相关的核心类,二者均提供了访问和操作 JVM 及底层系统资源的能力,但设计定位和使用方式有所不同。
1.System类
java.lang.System是一个最终类(final),且构造方法被私有化(无法实例化),所有方法和属性均为静态的,主要用于访问系统级资源(如标准输入输出、系统属性、环境变量)、执行系统级操作(如数组拷贝、垃圾回收、退出程序)等。
System类提供了三个常用的静态成员变量,用于处理标准输入、输出和错误流:
public static final InputStream in:标准输入流(通常对应键盘输入)。public static final PrintStream out:标准输出流(通常对应控制台输出)。public static final PrintStream err:标准错误流(用于输出错误信息,同样指向控制台,但输出优先级更高)。
// 标准输出
System.out.println("Hello, System!");
// 标准错误输出
System.err.println("This is an error message!");
(1)系统属性与环境变量
static Properties getProperties():获取当前 JVM 的系统属性集合(如 Java 版本、操作系统名称、用户目录等)。static String getProperty(String key):根据键获取指定的系统属性值。static String getenv(String name):获取指定的系统环境变量(如 PATH、JAVA_HOME)。
// 获取Java版本
String javaVersion = System.getProperty("java.version");
System.out.println("Java版本:" + javaVersion);
// 获取操作系统名称
String osName = System.getProperty("os.name");
System.out.println("操作系统:" + osName);
// 获取环境变量JAVA_HOME
String javaHome = System.getenv("JAVA_HOME");
System.out.println("JAVA_HOME:" + javaHome);
(2)数组拷贝
static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length):高效的数组拷贝方法(native 方法,底层由 C/C++ 实现,性能优于手动循环拷贝)。
src:源数组;srcPos:源数组起始拷贝位置;dest:目标数组;destPos:目标数组起始粘贴位置;length:拷贝的元素个数。
int[] src = {1, 2, 3, 4, 5};
int[] dest = new int[5];
// 将src中从索引0开始的3个元素,拷贝到dest的索引1开始的位置
System.arraycopy(src, 0, dest, 1, 3);
// 输出:[0, 1, 2, 3, 0]
System.out.println(Arrays.toString(dest));
(3)系统时间与计时
static long currentTimeMillis():返回当前时间与 1970 年 1 月 1 日 00:00:00 GMT 的时间差(毫秒数),常用于计时或生成时间戳。
public class Timetest {
public static void main(String[] args) {
long start = System.currentTimeMillis();//循环开始时的当前时间
int sum = 0;
for (int i = 0; i < 100000000; i++) {
sum += i;
}
long end = System.currentTimeMillis();//循环结束时的当前时间
System.out.println("循环时间:" + (end - start) + "ms");
}
}

发现循环时间为1毫秒,不对劲。问了AI,发现原因是:
Java 虚拟机的 JIT 编译器会对热点代码(频繁执行的代码)进行优化,比如循环展开、常量折叠、死代码消除等。对于你这个循环,sum += i 的计算结果没有被使用,JIT 可能会直接优化掉整个循环,导致输出的时间接近 0ms,无法反映真实的执行时间。采用static long nanoTime()。
static long nanoTime():返回 JVM 的高精度时间戳(纳秒级),适用于短时间间隔的精确测量(不受系统时间修改的影响)。
public class Timetest {
public static void main(String[] args) {
// 计算代码执行耗时
long start = System.nanoTime();
for (int i = 0; i < 100000; i++) {
// 模拟耗时操作
}
long end = System.nanoTime();
System.out.println("执行耗时:" + (end - start) + "纳秒");
}
}

(4)垃圾回收与退出程序
static void gc():建议 JVM 执行垃圾回收(注意:仅为建议,JVM 是否执行由垃圾回收器决定)。
class Person {
public void finalize() {
System.out.println("对象将作为垃圾回收...");
}
}
public class Test_gc {
public static void main(String[] args) {
Person p1 = new Person();
Person p2 = new Person();
//下面将变量设置为null
p1 = null;
p2 = null;
// 手动触发垃圾回收
System.gc();
}
}

2.Runtime类
java.lang.Runtime类用于表示当前 JVM 的运行时环境,每个 JVM 进程仅有一个Runtime实例(单例模式),通过它可以访问 JVM 的内存信息、执行外部进程、管理线程等,更侧重于对 JVM 自身运行状态的控制和查询。
Runtime类的构造方法被私有化,通过 ** 静态方法getRuntime()** 获取唯一实例:
Runtime runtime = Runtime.getRuntime();
(1)JVM 内存信息查询
用于获取 JVM 的内存分配、使用情况,是调优 JVM 的重要依据:
long totalMemory():返回 JVM 当前的总内存(堆内存),单位为字节(初始为 - Xms 指定的大小,可动态扩展至maxMemory())。long maxMemory():返回 JVM 可使用的最大内存(对应 - Xmx 指定的大小)。long freeMemory():返回 JVM 当前的空闲内存。
Runtime runtime = Runtime.getRuntime();
System.out.println("JVM总内存:" + runtime.totalMemory() / 1024 / 1024 + "MB");
System.out.println("JVM最大内存:" + runtime.maxMemory() / 1024 / 1024 + "MB");
System.out.println("JVM空闲内存:" + runtime.freeMemory() / 1024 / 1024 + "MB");
(2)执行外部进程
通过exec()方法可以启动操作系统的外部程序(如 exe、sh 脚本),实现 Java 程序与外部进程的交互:
Process exec(String command):执行指定的系统命令,返回Process对象用于控制外部进程。Process exec(String[] cmdarray):执行命令数组(更安全,避免命令注入)。
Runtime runtime = Runtime.getRuntime();
// 执行Windows的notepad.exe(记事本程序)
try {
Process process = runtime.exec("notepad.exe");
// 等待外部进程执行完毕
int exitCode = process.waitFor();
System.out.println("外部进程退出码:" + exitCode);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
(3)JVM 相关操作
void gc():与System.gc()功能一致,建议 JVM 执行垃圾回收(底层调用的是同一个实现)。void addShutdownHook(Thread hook):添加 JVM 关闭钩子线程(当 JVM 正常退出时,该线程会被执行,常用于资源释放)。void removeShutdownHook(Thread hook):移除已添加的关闭钩子线程。
Runtime runtime = Runtime.getRuntime();
// 添加关闭钩子:JVM退出时执行资源释放
runtime.addShutdownHook(new Thread(() -> {
System.out.println("JVM即将退出,释放资源中...");
// 模拟释放数据库连接、文件流等
}));
// 触发JVM退出
System.exit(0);
(4)其他方法(了解即可)
int availableProcessors():返回当前系统的可用处理器核心数(用于判断并发能力)。void halt(int status):强制终止 JVM 进程(与exit()不同,halt()不会执行关闭钩子和最终化方法,属于暴力退出)。
Runtime runtime = Runtime.getRuntime();
System.out.println("可用处理器核心数:" + runtime.availableProcessors());
三、Math类与Random类
在 Java API 中,Math类和Random类是处理数值计算与随机数生成的核心工具类,广泛应用于数学运算、游戏开发、数据模拟等场景。Math类提供了丰富的静态数学方法,而Random类专注于生成各种类型的随机数,二者相辅相成,共同满足程序中的数值处理需求。
1.Math类
java.lang.Math是一个最终类(final),构造方法被私有化(无法实例化),所有方法和常量均为静态的。它封装了常用的数学运算功能,如算术运算、三角函数、指数对数、取整、最值计算等,底层多基于原生代码实现,保证了运算效率。
Math类定义了两个常用的数学常量,精度为双精度浮点型(double):
public static final double PI:圆周率(π),约等于 3.141592653589793。public static final double E:自然常数(e),约等于 2.718281828459045。
// 计算圆的面积(面积=πr²)
double r = 5.0;
double area = Math.PI * Math.pow(r, 2);
System.out.println("圆的面积:" + area); // 输出约78.53981633974483
(1)算术运算:绝对值、最值、幂运算
static int abs(int a)/long abs(long a)/float abs(float a)/double abs(double a):返回参数的绝对值(支持多种数值类型)。static int max(int a, int b)/double max(double a, double b):返回两个数的最大值(同理min()返回最小值)。static double pow(double a, double b):返回a的b次幂(a^b)。static double sqrt(double a):返回a的平方根(仅支持非负数,负数返回NaN)。static double cbrt(double a):返回a的立方根(支持负数)。
System.out.println(Math.abs(-10)); // 输出10
System.out.println(Math.max(3.5, 2.8)); // 输出3.5
System.out.println(Math.pow(2, 3)); // 输出8.0(2的3次幂)
System.out.println(Math.sqrt(16)); // 输出4.0
(2)取整运算:四舍五入、向上 / 向下取整
Math类提供了多种取整方式,适用于不同的数值处理场景:
static long round(double a):将数值四舍五入为最接近的长整型(double参数)。static int round(float a):四舍五入为整型(float参数)。static double ceil(double a):向上取整(返回大于等于参数的最小整数)。static double floor(double a):向下取整(返回小于等于参数的最大整数)。static double rint(double a):返回最接近参数的整数(若距离相等,返回偶数)。
System.out.println(Math.round(3.6)); // 输出4
System.out.println(Math.ceil(3.2)); // 输出4.0
System.out.println(Math.floor(3.9)); // 输出3.0
System.out.println(Math.rint(2.5)); // 输出2.0(与2.5距离相等,返回偶数)
(3)三角函数与指数对数
适用于科学计算场景,所有参数均以弧度为单位(可通过toRadians()将角度转换为弧度):
static double sin(double a)/cos(double a)/tan(double a):正弦、余弦、正切函数。static double asin(double a)/acos(double a)/atan(double a):反正弦、反余弦、反正切函数。static double log(double a):自然对数(ln a)。static double log10(double a):以 10 为底的对数。static double exp(double a):自然常数 e 的 a 次幂(e^a)。static double toRadians(double angdeg):将角度转换为弧度。static double toDegrees(double angrad):将弧度转换为角度。
// 计算30度的正弦值(30度=π/6弧度)
double sin30 = Math.sin(Math.toRadians(30));
System.out.println("30度的正弦值:" + sin30); // 输出约0.5
System.out.println(Math.log(Math.E)); // 输出1.0(ln e=1)
(4)随机数(已过时,推荐使用 Random 类)
Math类提供了一个简单的随机数方法,但功能单一且随机性较弱:
static double random():返回一个[0.0, 1.0)区间的双精度随机数。
// 生成1-100的随机整数
int randomNum = (int) (Math.random() * 100 + 1);
System.out.println(randomNum);
2.Random类
java.util.Random类是 Java 提供的随机数生成器,用于生成伪随机数(基于种子值的算法生成,若种子相同,生成的随机数序列也相同)。它支持生成多种类型的随机数(int、long、float、double、boolean),功能比Math.random()更丰富、灵活。
Random类有两种构造方式,核心区别在于种子的来源:
无参构造:使用系统当前时间的纳秒数作为默认种子,每次运行生成的随机数序列不同。
Random random = new Random();
有参构造:指定固定种子(long类型),种子相同则生成的随机数序列完全一致(可用于复现测试场景)。
// 固定种子,每次运行生成的随机数序列相同
Random random = new Random(100);
(1)生成基本类型随机数
int nextInt():生成一个int范围内的随机整数(-2^31~2^31-1)。int nextInt(int bound):生成[0, bound)区间的随机整数(bound必须为正数,否则抛异常)。long nextLong():生成long范围内的随机长整数。float nextFloat():生成[0.0, 1.0)区间的随机浮点数。double nextDouble():生成[0.0, 1.0)区间的随机双精度数(与Math.random()等价)。boolean nextBoolean():生成随机的布尔值(true或false)。
Random random = new Random();
System.out.println(random.nextInt(100)); // 生成0-99的随机整数
System.out.println(random.nextBoolean()); // 生成true或false
System.out.println(random.nextDouble()); // 生成0.0-1.0的随机数
(2)生成指定范围的随机数
通过简单的数学运算,可生成任意区间的随机数:
- 生成
[a, b]区间的整数:random.nextInt(b - a + 1) + a - 生成
[a, b)区间的浮点数:a + random.nextDouble() * (b - a)
Random random = new Random();
// 生成10-20的随机整数(包含10和20)
int num1 = random.nextInt(11) + 10;
// 生成0.5-1.5的随机浮点数
double num2 = 0.5 + random.nextDouble() * 1.0;
System.out.println(num1);
System.out.println(num2);
(3)生成字节数组随机数
void nextBytes(byte[] bytes):将随机生成的字节填充到指定的字节数组中。
byte[] bytes = new byte[5];
Random random = new Random();
random.nextBytes(bytes);
System.out.println(Arrays.toString(bytes)); // 输出随机字节数组
(4)生成高斯分布随机数
double nextGaussian():生成服从标准正态分布的随机数(均值为 0,标准差为 1),适用于统计模拟场景。
Random random = new Random();
// 生成10个标准正态分布的随机数
for (int i = 0; i < 10; i++) {
System.out.println(random.nextGaussian());
}
四、日期时间类
java.time 包(JSR 310),提供了一套全新的日期时间 API,包括Instant、LocalDate、LocalTime、LocalDateTime、Period、Duration等核心类。这些类采用不可变设计,线程安全且 API 更直观,成为处理日期时间的首选。
1.Instant类
Instant类表示时间戳,对应 UTC(世界协调时间)的一个瞬时点,精确到纳秒级别,相当于 Unix 时间戳(从 1970 年 1 月 1 日 00:00:00 UTC 开始的毫秒数)的拓展。它主要用于记录事件的时间戳、跨时区的时间统一表示。
(1)获取当前时间戳
static Instant now():获取当前系统的瞬时时间戳。
Instant now = Instant.now();
System.out.println(now);
(2)时间戳的构建与转换
static Instant ofEpochMilli(long epochMilli):通过毫秒数构建Instant(对应 Unix 时间戳)。long toEpochMilli():将Instant转换为从 1970-01-01 00:00:00 UTC 开始的毫秒数。static Instant parse(CharSequence text):解析 ISO-8601 格式的字符串为Instant(如2025-12-21T08:15:30Z)
// 通过毫秒数构建
Instant instant = Instant.ofEpochMilli(System.currentTimeMillis());
// 转换为毫秒数
long milli = instant.toEpochMilli();
// 解析字符串
Instant parsed = Instant.parse("2025-12-21T08:15:30Z");
(3)时间戳的加减与比较
Instant plusSeconds(long seconds)/plusMillis(long millis)/plusNanos(long nanos):添加秒、毫秒、纳秒。Instant minusSeconds(long seconds):减少指定时间单位。int compareTo(Instant other):比较两个Instant的先后(返回负数表示当前对象更早,0 表示相等,正数表示更晚)。
Instant now = Instant.now();
Instant later = now.plusHours(1); // 1小时后
Instant earlier = now.minusMinutes(30); // 30分钟前
System.out.println(later.compareTo(now)); // 输出1(later更晚)
2.LocalData类
LocalDate类表示本地日期(年 - 月 - 日),不包含时间和时区信息,仅关注日期本身(如 2025-12-21)。
(1)获取当前日期与构建日期
static LocalDate now():获取当前系统的本地日期。static LocalDate of(int year, int month, int dayOfMonth):通过年、月、日构建LocalDate(月份支持数字 1-12 或Month枚举)。static LocalDate parse(CharSequence text):解析 ISO-8601 格式的字符串(如2025-12-21)为LocalDate。
// 当前日期
LocalDate today = LocalDate.now();
// 构建指定日期
LocalDate birthday = LocalDate.of(2000, 1, 1);
// 解析字符串
LocalDate parsed = LocalDate.parse("2025-12-21");
(2)日期的属性获取
int getYear():获取年份。Month getMonth():获取月份(返回Month枚举,如DECEMBER)。int getDayOfMonth():获取日期中的日。DayOfWeek getDayOfWeek():获取星期几(返回DayOfWeek枚举,如SUNDAY)。int lengthOfMonth():获取当月的天数。boolean isLeapYear():判断是否为闰年。
LocalDate date = LocalDate.of(2025, 12, 21);
System.out.println(date.getYear()); // 2025
System.out.println(date.getDayOfWeek()); // SUNDAY
System.out.println(date.isLeapYear()); // false
(3)日期的加减与调整
LocalDate plusYears(long years)/plusMonths(long months)/plusDays(long days):添加年、月、日。LocalDate minusWeeks(long weeks):减少指定周数。LocalDate withYear(int year):修改年份(返回新对象,原对象不变)。LocalDate with(TemporalAdjuster adjuster):使用时间调整器(如获取当月第一天、下一个周一)。
LocalDate date = LocalDate.now();
LocalDate nextYear = date.plusYears(1); // 明年今日
LocalDate firstDayOfMonth = date.with(TemporalAdjusters.firstDayOfMonth()); // 当月第一天
LocalDate nextMonday = date.with(TemporalAdjusters.next(DayOfWeek.MONDAY)); // 下一个周一
(4)日期比较
boolean isBefore(ChronoLocalDate other):判断当前日期是否在指定日期之前。boolean isAfter(ChronoLocalDate other):判断当前日期是否在指定日期之后。int compareTo(ChronoLocalDate other):比较日期先后。
LocalDate date1 = LocalDate.of(2025, 12, 20);
LocalDate date2 = LocalDate.of(2025, 12, 21);
System.out.println(date1.isBefore(date2)); // true
3.LocalTime类与LocalDataTime类
(1)LocalTime 类
LocalTime类表示本地时间(时:分: 秒。纳秒),不包含日期和时区信息,仅关注时间本身(如 14:30:45.123)。
常用方法
static LocalTime now():获取当前系统的本地时间。static LocalTime of(int hour, int minute, int second):通过时、分、秒构建LocalTime。LocalTime plusHours(long hours)/minusMinutes(long minutes):时间的加减。int getHour()/int getMinute():获取时、分等属性。boolean isBefore(LocalTime other):时间比较。
// 当前时间
LocalTime now = LocalTime.now();
// 构建指定时间
LocalTime time = LocalTime.of(14, 30, 0);
// 1小时后
LocalTime later = time.plusHours(1);
System.out.println(later); // 15:30:00
(2)LocalDateTime 类
LocalDateTime类是LocalDate和LocalTime的组合,表示本地日期时间(年 - 月 - 日 时:分: 秒。纳秒),不包含时区信息。
获取与构建
static LocalDateTime now():获取当前系统的本地日期时间。static LocalDateTime of(LocalDate date, LocalTime time):通过LocalDate和LocalTime构建。static LocalDateTime of(int year, int month, int dayOfMonth, int hour, int minute):直接指定年、月、日、时、分构建。static LocalDateTime parse(CharSequence text):解析 ISO-8601 格式的字符串(如2025-12-21T14:30:45)。
// 当前日期时间
LocalDateTime now = LocalDateTime.now();
// 通过日期和时间构建
LocalDate date = LocalDate.of(2025, 12, 21);
LocalTime time = LocalTime.of(14, 30);
LocalDateTime dateTime = LocalDateTime.of(date, time);
// 解析字符串
LocalDateTime parsed = LocalDateTime.parse("2025-12-21T14:30:45");
时区转换
LocalDateTime本身无时区,但可通过ZonedDateTime转换为带时区的时间:
// 转换为东八区时间
ZonedDateTime zoned = dateTime.atZone(ZoneId.of("Asia/Shanghai"));
(3)核心对比
| 类 | 包含信息 | 适用场景 |
|---|---|---|
| LocalTime | 时:分: 秒。纳秒 | 仅需时间的场景(如发车时间) |
| LocalDateTime | 年 - 月 - 日 时:分: 秒。纳秒 | 本地具体时间点(如订单支付时间) |
4.Period和Duration类
(1)Period 类
Period表示基于日期的时间间隔(年、月、日),适用于计算两个LocalDate之间的间隔。
常用方法
static Period between(LocalDate startDate, LocalDate endDate):计算两个日期之间的间隔。int getYears()/int getMonths()/int getDays():获取间隔的年、月、日。Period plusYears(long years):增加间隔的年数。Period multipliedBy(int n):将间隔乘以指定倍数。
LocalDate start = LocalDate.of(2020, 1, 1);
LocalDate end = LocalDate.of(2025, 12, 21);
// 计算间隔
Period period = Period.between(start, end);
System.out.println(period.getYears()); // 5
System.out.println(period.getMonths()); // 11
System.out.println(period.getDays()); // 20
(2)Duration 类
Duration表示基于时间的时间间隔(秒、纳秒),适用于计算两个Instant、LocalTime、LocalDateTime之间的间隔,支持天、时、分、秒、毫秒、纳秒的换算。
常用方法
static Duration between(Temporal start, Temporal end):计算两个时间对象之间的间隔。long toDays()/long toHours()/long toMinutes():将间隔转换为天、时、分。long getSeconds():获取间隔的秒数。Duration plusMinutes(long minutes):增加间隔的分钟数。
LocalTime start = LocalTime.of(10, 0, 0);
LocalTime end = LocalTime.of(14, 30, 0);
// 计算时间间隔
Duration duration = Duration.between(start, end);
System.out.println(duration.toHours()); // 4
System.out.println(duration.toMinutes()); // 270(4小时30分钟)
// 计算Instant的间隔
Instant instant1 = Instant.now();
Instant instant2 = instant1.plusSeconds(120);
Duration dur = Duration.between(instant1, instant2);
System.out.println(dur.getSeconds()); // 120
(3)核心对比
| 类 | 间隔单位 | 适用的时间类型 |
|---|---|---|
| Period | 年、月、日 | LocalDate |
| Duration | 秒、纳秒(可换算天 / 时 / 分) | Instant、LocalTime、LocalDateTime |
五、包装类
在 Java 中,包装类(Wrapper Class) 是为 8 种基本数据类型提供的引用类型封装,位于java.lang包下。Java 是面向对象的语言,但基本数据类型不具备对象的特性(如无法调用方法、不能作为泛型参数、无法参与多态等),包装类的出现弥补了这一缺陷,实现了基本数据类型与对象的相互转换,同时提供了丰富的数值处理方法。
Java 为 8 种基本数据类型分别提供了对应的包装类,可分为两类:
数值型包装类(继承自Number类)
| 基本数据类型 | 对应的包装类 |
|---|---|
| byte | Byte |
| short | Short |
| int | Integer |
| long | Long |
| float | Float |
| double | Double |
非数值型包装类
| 基本数据类型 | 对应的包装类 |
|---|---|
| char | Character |
| boolean | Boolean |
基本数据类型与包装类的转换是包装类最常用的功能,包括装箱和拆箱两种操作。装箱:基本数据类型 → 包装类对象(引用数据类型);拆箱:包装类对象(引用数据类型) → 基本数据类型。
自动装箱:编译器自动将基本数据类型转换为对应的包装类对象,无需手动调用包装类的valueOf()方法。
自动拆箱:编译器自动将包装类对象转换为对应的基本数据类型,无需手动调用包装类的xxxValue()方法(如intValue())。
public class Test03 {
public static void main(String[] args) {
int a = 20;
Integer in =a;//自动装箱
System.out.println(in);
int l =in;//自动拆箱
System.out.println(l);
}
}

注意:如果包装类对象为null,自动拆箱会抛出NullPointerException(这段代码中in有值,所以不会出现此问题)。
手动装箱:通过Integer类的构造方法,将基本类型int的20封装为Integer包装类对象。
手动拆箱:调用Integer类的intValue()方法,将Integer包装类对象转换为对应的int基本数据类型。
public class Test04 {
public static void main(String[] args) {
Integer num = new Integer(20);//手动装箱
int sum = num.intValue() + 10;//手动拆箱
System.out.println("将Integeer类型的值转为int类型后与10相加的结果:" + sum);
System.out.println("返回表示10的Integer实例为:" + Integer.valueOf(10));
int w = Integer.parseInt("20") + 32;
System.out.println("将字符串\"20\"转换为int类型后与32相加的结果:" + w);
}
}

六、正则表达式
正则表达式(Regular Expression)是一种用于匹配、查找、替换字符串的强大工具,它通过预定义的元字符和普通字符组成的模式,实现对字符串的灵活匹配。Java 中通过java.util.regex包下的Pattern类和Matcher类提供正则表达式的核心支持,同时String类也内置了便捷的正则处理方法,让字符串的正则操作更加简洁。
1.元字符
元字符是正则表达式的核心,分为基本元字符、限定符、分组与断言等类型,用于描述字符的匹配规则。
| 元字符 | 含义 | 示例 |
|---|---|---|
. |
匹配任意单个字符(除了换行符\n) |
a.b匹配a1b、aab |
\d |
匹配任意数字(0-9),等价于[0-9] |
\d{3}匹配123 |
\D |
匹配任意非数字字符,等价于[^0-9] |
\D匹配a、@ |
\w |
匹配任意单词字符(字母、数字、下划线),等价于[a-zA-Z0-9_] |
\w+匹配java123 |
\W |
匹配任意非单词字符,等价于[^a-zA-Z0-9_] |
\W匹配@、# |
\s |
匹配任意空白字符(空格、制表符\t、换行符\n等) |
\s匹配空格、\t |
\S |
匹配任意非空白字符 | \S匹配a、1 |
[] |
字符集,匹配括号内的任意一个字符(支持范围,如[a-z]表示小写字母) |
[abc]匹配a、b |
[^] |
否定字符集,匹配不在括号内的任意一个字符 | [^abc]匹配d、1 |
| ` | ` | 或运算,匹配左边或右边的表达式 |
* |
匹配前面的字符 0 次或多次 | a*匹配""、a、aa |
+ |
匹配前面的字符 1 次或多次 | a+匹配a、aa |
? |
匹配前面的字符 0 次或 1 次(可选) | a?匹配""、a |
{n} |
匹配前面的字符恰好 n 次 | a{3}匹配aaa |
{n,} |
匹配前面的字符至少 n 次 | a{2,}匹配aa、aaa |
{n,m} |
匹配前面的字符至少 n 次,最多 m 次 | a{2,3}匹配aa、aaa |
^ |
匹配字符串的开头 | ^java匹配java123 |
$ |
匹配字符串的结尾 | java$匹配123java |
\b |
匹配单词边界(单词与非单词的分隔处) | \bjava\b匹配java(不匹配javac) |
\B |
匹配非单词边界 | \Bjava\B匹配javac中的java |
() |
分组,将括号内的表达式作为一个整体,可结合限定符使用 | |
\n |
反向引用,引用第 n 个分组的匹配结果(n 从 1 开始) |
2.Pattern类和Matcher类
java.util.regex.Pattern(模式类)和java.util.regex.Matcher(匹配器类)是 Java 处理正则表达式的核心类,Pattern用于编译正则表达式(生成模式对象),Matcher用于对字符串进行匹配操作,二者配合使用可实现复杂的正则处理。
(1)Pattern 类
Pattern 类是不可变的、线程安全的,它的核心作用是编译正则表达式(将字符串形式的正则表达式转换为高效的内部表示),避免重复编译提升性能。
常用方法
static Pattern compile(String regex):编译正则表达式,返回 Pattern 对象(核心方法)。static Pattern compile(String regex, int flags):编译正则表达式并指定匹配标志(如Pattern.CASE_INSENSITIVE表示忽略大小写)。Matcher matcher(CharSequence input):创建一个 Matcher 对象,用于对输入字符串进行匹配。static boolean matches(String regex, CharSequence input):静态方法,直接匹配整个字符串(等价于编译后调用matcher.matches())。String[] split(CharSequence input):按正则表达式拆分字符串(与 String 的 split 方法类似)。
(2)Matcher 类
Matcher 类是非线程安全的,它通过 Pattern 对象创建,用于对字符串进行匹配、查找、替换等操作,提供了丰富的匹配状态和方法。
常用方法
- 匹配整个字符串:
boolean matches():判断整个输入字符串是否完全匹配正则表达式。 - 查找子串:
boolean find():在输入字符串中查找下一个匹配的子串(多次调用可遍历所有匹配项)。 - 获取匹配结果:
String group():返回当前匹配的子串;int start():返回当前匹配子串的起始索引;int end():返回当前匹配子串的结束索引(不包含)。
- 替换操作:
String replaceAll(String replacement):替换所有匹配的子串;String replaceFirst(String replacement):替换第一个匹配的子串。
匹配字符串中的所有数字:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexDemo {
public static void main(String[] args) {
// 1. 定义正则表达式和输入字符串
String regex = "\\d+"; // 匹配一个或多个数字
String input = "Java123Regex456Pattern789";
// 2. 编译正则表达式
Pattern pattern = Pattern.compile(regex);
// 3. 创建Matcher对象
Matcher matcher = pattern.matcher(input);
// 4. 查找所有匹配的子串
while (matcher.find()) {
System.out.println("匹配到的子串:" + matcher.group());
System.out.println("起始索引:" + matcher.start() + ",结束索引:" + matcher.end());
}
}
}

3.String类对正则表达式的支持
为了简化开发,String类内置了多个直接支持正则表达式的方法,这些方法底层其实是调用了Pattern和Matcher类的功能,但使用起来更便捷。
(1)匹配操作:matches(String regex)
- 作用:判断整个字符串是否完全匹配指定的正则表达式(返回 boolean)。
- 注意:与 Matcher 的
matches()方法一致,需匹配整个字符串,而非子串。
判断是否为合法的手机号(以 1 开头,11 位数字):
String phone = "13812345678";
boolean isPhone = phone.matches("^1[3-9]\\d{9}$");
System.out.println(isPhone);
(2)拆分操作:split(String regex)
- 作用:按正则表达式拆分字符串,返回字符串数组(支持指定拆分次数)。
- 重载方法:
split(String regex, int limit):limit 指定拆分的最大次数。
按任意空白字符拆分字符串:
String str = "Java Regex Pattern";
String[] arr = str.split("\\s+"); // 按一个或多个空白字符拆分
System.out.println(Arrays.toString(arr)); // 输出[Java, Regex, Pattern]
(3)替换操作
replaceAll(String regex, String replacement):替换所有匹配的子串;replaceFirst(String regex, String replacement):替换第一个匹配的子串。
替换字符串中的所有数字为*:
String str = "Java123Regex456";
String newStr = str.replaceAll("\\d+", "*");
System.out.println(newStr); // 输出Java*Regex*更多推荐


所有评论(0)