背景

本文是《Java 后端从小白到大神》修仙系列第八篇,正式进入Java后端世界,本篇文章主要聊Java基础中的常用基础类。Java提供了丰富的基础类库,这些类是我们日常开发中最常用的工具,掌握它们对于编写高效、优雅的Java代码至关重要。若想详细学习请点击首篇博文,我们开始吧。

文章概览

  1. 根类与基础工具类
    • Object 类
    • Math 类
    • Character 类
  2. 字符串相关类
    • String 类
    • StringBuffer 类
    • StringBuilder 类
  3. 数值相关类
    • Number 抽象类
    • 包装类(Integer, Double等)
  4. 日期时间类
    • java.time 包介绍
    • 常用日期时间类
  5. 输入输出类
    • Scanner 类
  6. 正则表达式
    • Pattern 与 Matcher 类
  7. 类之间的比较与最佳实践

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 数值处理的最佳实践

  1. 包装类与基本类型

    • 方法参数和局部变量使用基本类型(性能更好)
    • 集合中使用包装类(泛型要求)
    • 自动装箱和拆箱会影响性能,频繁操作时应注意
  2. 数值转换

    • 使用包装类的 parseXxx() 方法进行字符串到数值的转换
    • 使用包装类的 valueOf() 方法创建包装对象(利用缓存)
  3. 数学运算

    • 简单运算使用 Math 类的静态方法
    • 复杂运算考虑使用 BigDecimal(高精度)

7.4 输入处理的最佳实践

  1. Scanner 的使用

    • 使用 try-with-resources 确保 Scanner 正确关闭
    • 读取不同类型数据时注意输入顺序
    • 处理用户输入时要考虑异常情况
  2. 正则表达式的使用

    • 复杂正则表达式应预编译为 Pattern 对象(提高性能)
    • 使用合理的正则表达式,避免过度复杂
    • 注意正则表达式的转义字符

总结

类别 类名 核心特性 典型应用场景
根类 Object 所有类的超类 提供对象的基本行为
工具类 Math 静态数学方法 数学计算
Character 字符操作 字符判断和转换
字符串 String 不可变字符序列 字符串常量、频繁读操作
StringBuffer 可变,线程安全 多线程字符串修改
StringBuilder 可变,非线程安全 单线程字符串修改
数值 Integer, Double 等 包装类 基本类型的对象表示
日期时间 LocalDate, LocalTime, LocalDateTime 不可变,线程安全 日期时间处理
输入 Scanner 输入处理 读取用户输入或文件内容
正则 Pattern, Matcher 正则表达式处理 字符串匹配、替换、分割

最佳实践总结

  1. 字符串处理

    • 优先使用 String 处理常量字符串
    • 频繁修改时使用 StringBuilder(单线程)或 StringBuffer(多线程)
  2. 日期时间

    • 优先使用 java.time 包下的类
    • 根据需要选择合适的日期时间类
  3. 数值处理

    • 合理使用基本类型和包装类
    • 注意包装类的缓存机制
  4. 输入输出

    • 使用 Scanner 简化输入处理
    • 注意资源的正确关闭
  5. 正则表达式

    • 复杂正则表达式预编译为 Pattern 对象
    • 合理使用正则表达式,避免过度复杂

通过掌握这些常用基础类的使用方法和技术原理,我们可以编写更加高效、优雅的Java代码。这些类是Java开发的基础,也是我们日常工作中最常用的工具,深入理解它们对于成为一名优秀的Java开发者至关重要。