背景
本文是《Java 后端从小白到大神》修仙系列第八篇,正式进入Java后端世界,本篇文章主要聊Java基础中的常用基础类。Java提供了丰富的基础类库,这些类是我们日常开发中最常用的工具,掌握它们对于编写高效、优雅的Java代码至关重要。若想详细学习请点击首篇博文,我们开始吧。
文章概览
- 根类与基础工具类
- Object 类
- Math 类
- Character 类
- 字符串相关类
- String 类
- StringBuffer 类
- StringBuilder 类
- 数值相关类
- Number 抽象类
- 包装类(Integer, Double等)
- 日期时间类
- 输入输出类
- 正则表达式
- 类之间的比较与最佳实践
1. 根类与基础工具类
1.1 Object 类
作用:Object 是 Java 中所有类的超类,所有类都直接或间接继承自 Object。它提供了一些基础方法,是Java对象的通用行为定义。
核心方法:
toString():返回对象的字符串表示形式
equals(Object obj):比较两个对象是否相等
hashCode():返回对象的哈希码值
getClass():返回对象的运行时类
clone():创建并返回对象的副本
finalize():对象被垃圾回收前调用的方法
技术原理:
- Object 类是 Java 类型系统的根,所有类都继承自它
- 它提供了对象的基本行为,确保所有对象都具有这些方法
- 子类可以重写这些方法以提供更具体的实现
代码示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
// Object 类的基本使用
Object obj = new Object();
System.out.println(obj.toString()); // 输出:java.lang.Object@哈希码
System.out.println(obj.getClass()); // 输出:class java.lang.Object
// 自定义类重写 Object 方法
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + "}";
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age && Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
// 使用自定义类
Person person1 = new Person("张三", 20);
Person person2 = new Person("张三", 20);
System.out.println(person1); // 调用 toString()
System.out.println(person1.equals(person2)); // 调用 equals()
System.out.println(person1.hashCode()); // 调用 hashCode()
|
1.2 Math 类
作用:Math 类提供了一系列静态数学方法,用于执行基本的数学运算。
核心方法:
- 算术运算:
abs(), max(), min(), pow(), sqrt()
- 三角函数:
sin(), cos(), tan()
- 指数对数:
exp(), log(), log10()
- 取整运算:
ceil(), floor(), round()
- 随机数:
random()
技术原理:
- Math 类是一个 final 类,不能被继承
- 所有方法都是静态的,不需要创建实例
- 内部使用了高效的算法实现数学运算
代码示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
// 基本数学运算
System.out.println(Math.abs(-10)); // 输出:10
System.out.println(Math.max(10, 20)); // 输出:20
System.out.println(Math.min(10, 20)); // 输出:10
System.out.println(Math.pow(2, 3)); // 输出:8.0
System.out.println(Math.sqrt(25)); // 输出:5.0
// 取整运算
System.out.println(Math.ceil(3.14)); // 输出:4.0
System.out.println(Math.floor(3.99)); // 输出:3.0
System.out.println(Math.round(3.6)); // 输出:4
// 随机数
System.out.println(Math.random()); // 输出:0.0-1.0之间的随机数
System.out.println((int)(Math.random() * 100)); // 输出:0-99之间的随机整数
|
1.3 Character 类
作用:Character 类是 char 类型的包装类,提供了一系列用于处理字符的静态方法。
核心方法:
- 字符判断:
isLetter(), isDigit(), isWhitespace(), isUpperCase(), isLowerCase()
- 字符转换:
toUpperCase(), toLowerCase(), toString()
技术原理:
- Character 类将 char 类型包装为对象,提供了更多的操作方法
- 它是一个 final 类,不能被继承
- 内部使用了缓存机制,对于常用字符(\u0000-\u007F)会缓存对应的 Character 对象
代码示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
// 字符判断
char c1 = 'A';
char c2 = '5';
char c3 = ' ';
System.out.println(Character.isLetter(c1)); // 输出:true
System.out.println(Character.isDigit(c2)); // 输出:true
System.out.println(Character.isWhitespace(c3)); // 输出:true
System.out.println(Character.isUpperCase(c1)); // 输出:true
// 字符转换
System.out.println(Character.toLowerCase(c1)); // 输出:a
System.out.println(Character.toUpperCase('b')); // 输出:B
// 字符对象创建
Character ch1 = 'A'; // 自动装箱
Character ch2 = Character.valueOf('B'); // 使用静态方法
System.out.println(ch1.toString()); // 输出:A
|
2. 字符串相关类
2.1 String 类
作用:String 类表示不可变的字符序列,是 Java 中最常用的类之一。
技术原理:
- 底层基于
final char[] 数组存储数据
- 不可变性:一旦创建,内容不可修改,修改操作会生成新的 String 对象
- 字符串常量池:相同内容的字符串会共享同一个对象,提高内存利用率
核心方法:
- 字符串操作:
length(), charAt(), substring(), concat(), replace()
- 字符串判断:
equals(), equalsIgnoreCase(), contains(), startsWith(), endsWith()
- 字符串转换:
toCharArray(), toLowerCase(), toUpperCase(), trim()
- 字符串分割:
split(), join()
代码示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
// 字符串创建
String str1 = "Hello";
String str2 = new String("Hello");
String str3 = String.valueOf(123);
// 字符串操作
System.out.println(str1.length()); // 输出:5
System.out.println(str1.charAt(0)); // 输出:H
System.out.println(str1.substring(1, 3)); // 输出:el
System.out.println(str1.concat(" World")); // 输出:Hello World
System.out.println(str1.replace("H", "h")); // 输出:hello
// 字符串判断
System.out.println(str1.equals(str2)); // 输出:true
System.out.println(str1.equalsIgnoreCase("HELLO")); // 输出:true
System.out.println(str1.contains("ell")); // 输出:true
System.out.println(str1.startsWith("He")); // 输出:true
System.out.println(str1.endsWith("lo")); // 输出:true
// 字符串转换
System.out.println(str1.toLowerCase()); // 输出:hello
System.out.println(str1.toUpperCase()); // 输出:HELLO
System.out.println(" Hello ".trim()); // 输出:Hello
// 字符串分割与拼接
String[] parts = "a,b,c".split(",");
System.out.println(parts[0]); // 输出:a
String joined = String.join("-", "a", "b", "c");
System.out.println(joined); // 输出:a-b-c
|
2.2 StringBuffer 类
作用:StringBuffer 类表示可变的字符序列,线程安全,适用于多线程环境。
技术原理:
- 底层基于
char[] 数组存储数据
- 可变:修改操作直接修改内部数组,不会创建新对象
- 线程安全:所有公共方法都使用
synchronized 修饰
- 动态扩容:默认容量为16,当容量不足时会自动扩容(扩容公式:新容量 = 旧容量*2 + 2)
核心方法:
- 字符串修改:
append(), insert(), delete(), replace(), reverse()
- 其他方法:
length(), capacity(), toString()
代码示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
// StringBuffer 创建
StringBuffer sb = new StringBuffer("Java"); // 指定初始字符串
StringBuffer sb2 = new StringBuffer(32); // 指定初始容量
// 字符串修改
System.out.println(sb.append("!")); // 输出:Java!
System.out.println(sb.insert(4, " Core")); // 输出:Java Core!
System.out.println(sb.delete(4, 9)); // 输出:Java!
System.out.println(sb.replace(0, 4, "Hello")); // 输出:Hello!
System.out.println(sb.reverse()); // 输出:!olleH
// 容量相关
System.out.println(sb.length()); // 输出:6
System.out.println(sb.capacity()); // 输出:16(默认容量)
// 转换为 String
String result = sb.toString();
System.out.println(result); // 输出:!olleH
|
2.3 StringBuilder 类
作用:StringBuilder 类表示可变的字符序列,非线程安全,适用于单线程环境。
技术原理:
- 底层基于
char[] 数组存储数据(与 StringBuffer 相同)
- 可变:修改操作直接修改内部数组,不会创建新对象(与 StringBuffer 相同)
- 非线程安全:方法没有使用
synchronized 修饰,性能比 StringBuffer 更高
- 动态扩容:默认容量为16,当容量不足时会自动扩容(扩容公式:新容量 = 旧容量*2 + 2)(与 StringBuffer 相同)
核心方法:
- 与 StringBuffer 基本相同:
append(), insert(), delete(), replace(), reverse() 等
代码示例:
1
2
3
4
5
6
7
8
9
10
11
|
// StringBuilder 创建
StringBuilder sb = new StringBuilder("Java"); // 指定初始字符串
// 字符串修改
System.out.println(sb.append("!")); // 输出:Java!
System.out.println(sb.insert(4, " Core")); // 输出:Java Core!
System.out.println(sb.reverse()); // 输出:!eroC avaJ
// 转换为 String
String result = sb.toString();
System.out.println(result); // 输出:!eroC avaJ
|
2.4 字符串类的比较
| 特性 |
String |
StringBuffer |
StringBuilder |
| 可变性 |
不可变 |
可变 |
可变 |
| 线程安全 |
安全(不可变) |
安全(synchronized) |
不安全 |
| 性能 |
频繁修改时性能差 |
性能适中 |
性能最好 |
| 适用场景 |
字符串常量、频繁读操作 |
多线程环境下的字符串修改 |
单线程环境下的字符串修改 |
3. 数值相关类
3.1 Number 抽象类
作用:Number 是所有数值包装类的抽象父类,提供了将数值转换为不同基本类型的方法。
核心方法:
byteValue(), shortValue(), intValue(), longValue(), floatValue(), doubleValue()
技术原理:
- Number 是一个抽象类,定义了数值类型的通用行为
- 具体的数值包装类(如 Integer, Double 等)都继承自 Number
3.2 包装类
作用:包装类将基本数据类型包装为对象,提供了更多的操作方法。
常用包装类:
Integer:int 的包装类
Double:double 的包装类
Boolean:boolean 的包装类
Character:char 的包装类
Byte:byte 的包装类
Short:short 的包装类
Long:long 的包装类
Float:float 的包装类
技术原理:
- 包装类提供了自动装箱和自动拆箱功能,方便在基本类型和对象之间转换
- 对于常用数值,包装类实现了缓存机制,提高性能
代码示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
// 自动装箱与拆箱
Integer num1 = 100; // 自动装箱
int num2 = num1; // 自动拆箱
// 包装类的方法
System.out.println(Integer.MAX_VALUE); // 输出:2147483647
System.out.println(Integer.MIN_VALUE); // 输出:-2147483648
System.out.println(Integer.parseInt("123")); // 输出:123
System.out.println(Integer.valueOf("456")); // 输出:456
System.out.println(Integer.toBinaryString(10)); // 输出:1010
// 缓存机制
Integer a = 127;
Integer b = 127;
System.out.println(a == b); // 输出:true(缓存范围内)
Integer c = 128;
Integer d = 128;
System.out.println(c == d); // 输出:false(超出缓存范围)
|
4. 日期时间类
4.1 java.time 包介绍
作用:java.time 包是 Java 8 引入的日期时间 API,提供了更强大、更灵活的日期时间处理功能。
核心特性:
- 不可变性:所有类都是不可变的,线程安全
- 清晰的 API 设计:不同的类表示不同的时间概念
- 丰富的操作方法:支持日期时间的计算、格式化等操作
4.2 常用日期时间类
LocalDate:表示日期(年、月、日)
LocalTime:表示时间(时、分、秒、纳秒)
LocalDateTime:表示日期和时间
Instant:表示时间戳(从 1970-01-01T00:00:00Z 开始的秒数)
Duration:表示时间间隔
Period:表示日期间隔
DateTimeFormatter:日期时间格式化
代码示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
// LocalDate
LocalDate date = LocalDate.now(); // 当前日期
System.out.println(date); // 输出:2026-03-22
LocalDate birthday = LocalDate.of(1990, 1, 1); // 指定日期
System.out.println(birthday); // 输出:1990-01-01
LocalDate nextWeek = date.plusWeeks(1); // 一周后
System.out.println(nextWeek); // 输出:2026-03-29
// LocalTime
LocalTime time = LocalTime.now(); // 当前时间
System.out.println(time); // 输出:10:30:45.123
LocalTime meetingTime = LocalTime.of(14, 30); // 指定时间
System.out.println(meetingTime); // 输出:14:30
// LocalDateTime
LocalDateTime dateTime = LocalDateTime.now(); // 当前日期时间
System.out.println(dateTime); // 输出:2026-03-22T10:30:45.123
// 日期时间格式化
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formattedDateTime = dateTime.format(formatter);
System.out.println(formattedDateTime); // 输出:2026-03-22 10:30:45
// 解析日期时间字符串
LocalDateTime parsedDateTime = LocalDateTime.parse("2026-03-22 10:30:45", formatter);
System.out.println(parsedDateTime); // 输出:2026-03-22T10:30:45
// Duration(时间间隔)
Duration duration = Duration.between(LocalTime.of(10, 0), LocalTime.of(12, 30));
System.out.println(duration.toHours()); // 输出:2
System.out.println(duration.toMinutes()); // 输出:150
// Period(日期间隔)
Period period = Period.between(LocalDate.of(2026, 1, 1), LocalDate.of(2026, 3, 22));
System.out.println(period.getMonths()); // 输出:2
System.out.println(period.getDays()); // 输出:21
|
5. 输入输出类
5.1 Scanner 类
作用:Scanner 类用于读取用户输入或文件内容,是处理输入的便捷工具。
技术原理:
- Scanner 可以从多种输入源读取数据,如 System.in、文件、字符串等
- 它会将输入分解为标记(tokens),默认使用空白字符作为分隔符
- 提供了多种方法来读取不同类型的数据
核心方法:
next():读取下一个标记
nextLine():读取一整行
nextInt(), nextDouble() 等:读取特定类型的数据
hasNext():检查是否还有下一个标记
close():关闭 Scanner
代码示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
// 从控制台读取输入
Scanner scanner = new Scanner(System.in);
System.out.print("请输入姓名: ");
String name = scanner.nextLine();
System.out.print("请输入年龄: ");
int age = scanner.nextInt();
System.out.println("你好, " + name + "! 你今年" + age + "岁。");
// 从字符串读取
String input = "Hello 123 3.14";
Scanner stringScanner = new Scanner(input);
System.out.println(stringScanner.next()); // 输出:Hello
System.out.println(stringScanner.nextInt()); // 输出:123
System.out.println(stringScanner.nextDouble()); // 输出:3.14
// 关闭 Scanner
scanner.close();
stringScanner.close();
|
6. 正则表达式
6.1 Pattern 与 Matcher 类
作用:Pattern 和 Matcher 类用于处理正则表达式,提供了强大的字符串匹配、替换和分割功能。
技术原理:
- Pattern 类表示编译后的正则表达式模式
- Matcher 类用于对输入字符串应用正则表达式模式
- 正则表达式是一种用于匹配字符串的模式语言
核心方法:
- Pattern:
compile(), matcher(), split()
- Matcher:
find(), matches(), group(), replaceAll(), replaceFirst()
代码示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
// 编译正则表达式模式
Pattern pattern = Pattern.compile("\\d+"); // 匹配一个或多个数字
// 创建 Matcher
Matcher matcher = pattern.matcher("a1b23c456");
// 查找所有匹配
while (matcher.find()) {
System.out.println("找到匹配: " + matcher.group());
System.out.println("起始位置: " + matcher.start());
System.out.println("结束位置: " + matcher.end());
}
// 替换匹配
String input = "a1b23c456";
String replaced = pattern.matcher(input).replaceAll("X");
System.out.println("替换后: " + replaced); // 输出:aXbXcX
// 分割字符串
Pattern splitPattern = Pattern.compile(",");
String[] parts = splitPattern.split("a,b,c,d");
for (String part : parts) {
System.out.println(part);
}
// 完整匹配
Pattern fullPattern = Pattern.compile("\\d{4}-\\d{2}-\\d{2}"); // 日期格式
Matcher fullMatcher = fullPattern.matcher("2026-03-22");
System.out.println("完整匹配: " + fullMatcher.matches()); // 输出:true
|
7. 类之间的比较与最佳实践
7.1 字符串类的选择
| 场景 |
推荐类 |
理由 |
| 字符串常量 |
String |
不可变性,内存效率高 |
| 频繁修改字符串(单线程) |
StringBuilder |
可变,性能最好 |
| 频繁修改字符串(多线程) |
StringBuffer |
可变,线程安全 |
| 字符串拼接 |
StringBuilder |
性能优于 String 的 + 操作 |
7.2 日期时间类的选择
| 场景 |
推荐类 |
理由 |
| 仅日期 |
LocalDate |
专注于日期处理 |
| 仅时间 |
LocalTime |
专注于时间处理 |
| 日期和时间 |
LocalDateTime |
同时处理日期和时间 |
| 时间戳 |
Instant |
高精度时间戳,适用于时间计算 |
| 时间间隔 |
Duration |
处理时间差 |
| 日期间隔 |
Period |
处理日期间隔 |
| 日期时间格式化 |
DateTimeFormatter |
灵活的格式化选项 |
7.3 数值处理的最佳实践
-
包装类与基本类型:
- 方法参数和局部变量使用基本类型(性能更好)
- 集合中使用包装类(泛型要求)
- 自动装箱和拆箱会影响性能,频繁操作时应注意
-
数值转换:
- 使用包装类的 parseXxx() 方法进行字符串到数值的转换
- 使用包装类的 valueOf() 方法创建包装对象(利用缓存)
-
数学运算:
- 简单运算使用 Math 类的静态方法
- 复杂运算考虑使用 BigDecimal(高精度)
7.4 输入处理的最佳实践
-
Scanner 的使用:
- 使用 try-with-resources 确保 Scanner 正确关闭
- 读取不同类型数据时注意输入顺序
- 处理用户输入时要考虑异常情况
-
正则表达式的使用:
- 复杂正则表达式应预编译为 Pattern 对象(提高性能)
- 使用合理的正则表达式,避免过度复杂
- 注意正则表达式的转义字符
总结
| 类别 |
类名 |
核心特性 |
典型应用场景 |
| 根类 |
Object |
所有类的超类 |
提供对象的基本行为 |
| 工具类 |
Math |
静态数学方法 |
数学计算 |
|
Character |
字符操作 |
字符判断和转换 |
| 字符串 |
String |
不可变字符序列 |
字符串常量、频繁读操作 |
|
StringBuffer |
可变,线程安全 |
多线程字符串修改 |
|
StringBuilder |
可变,非线程安全 |
单线程字符串修改 |
| 数值 |
Integer, Double 等 |
包装类 |
基本类型的对象表示 |
| 日期时间 |
LocalDate, LocalTime, LocalDateTime |
不可变,线程安全 |
日期时间处理 |
| 输入 |
Scanner |
输入处理 |
读取用户输入或文件内容 |
| 正则 |
Pattern, Matcher |
正则表达式处理 |
字符串匹配、替换、分割 |
最佳实践总结:
-
字符串处理:
- 优先使用 String 处理常量字符串
- 频繁修改时使用 StringBuilder(单线程)或 StringBuffer(多线程)
-
日期时间:
- 优先使用 java.time 包下的类
- 根据需要选择合适的日期时间类
-
数值处理:
-
输入输出:
- 使用 Scanner 简化输入处理
- 注意资源的正确关闭
-
正则表达式:
- 复杂正则表达式预编译为 Pattern 对象
- 合理使用正则表达式,避免过度复杂
通过掌握这些常用基础类的使用方法和技术原理,我们可以编写更加高效、优雅的Java代码。这些类是Java开发的基础,也是我们日常工作中最常用的工具,深入理解它们对于成为一名优秀的Java开发者至关重要。