【2025最新】 Java入门到实战:包装类、字符串转换、equals/toString + 可变字符串,一篇搞定开发高频场景(含案例解析)

一、基本类型包装类

1.1 概念引入

Java 是面向对象的编程语言,但 8 种基本数据类型(byte、short、int、long、float、double、char、boolean)并不属于对象体系。为了让基本类型具备对象特性(如可存储在集合中、可调用方法),Java 提供了对应的包装类,将基本类型 "包装" 成对象。

1.2 包装类对应关系

基本类型 包装类 核心用途
byte Byte 字节型数据封装
short Short 短整型数据封装
int Integer 整型数据封装(最常用)
long Long 长整型数据封装
float Float 单精度浮点型数据封装
double Double 双精度浮点型数据封装
char Character 字符型数据封装
boolean Boolean 布尔型数据封装

1.3 包装类的特性

  • 包装类是不可变类:对象创建后,其内部值无法修改。
  • 提供了常量(如Integer.MAX_VALUEDouble.NaN)和工具方法(如类型转换、进制转换)。
  • 包装类是final修饰的类,不能被继承;
  • 内部封装了对应的基本类型值,提供了属性和方法操作该值;
  • 支持基本类型与对象之间的转换(装箱 / 拆箱)。

二、装箱与拆箱

2.1 手动装箱(基本类型→包装类)

通过包装类的构造方法或valueOf()方法,将基本类型转换为包装类对象。

java 复制代码
public class BoxDemo {
    public static void main(String[] args) {
        // 1. 构造方法装箱(JDK9后已标记过时,推荐valueOf)
        Integer num1 = new Integer(10);
        Character ch1 = new Character('a');
        
        // 2. valueOf()方法装箱(推荐,有缓存优化)
        Integer num2 = Integer.valueOf(20);
        Double num3 = Double.valueOf(3.14);
        
        System.out.println("手动装箱结果:" + num1 + ", " + num2);
    }
}

2.2 手动拆箱(包装类→基本类型)

通过包装类的xxxValue()方法(如intValue()doubleValue()),将包装类对象转换为基本类型。

java 复制代码
public class UnboxDemo {
    public static void main(String[] args) {
        Integer numObj = Integer.valueOf(100);
        Double doubleObj = Double.valueOf(2.5);
        
        // 拆箱为基本类型
        int num = numObj.intValue();
        double d = doubleObj.doubleValue();
        
        System.out.println("拆箱后基本类型:" + num + ", " + d);
    }
}

2.3 自动装箱与自动拆箱(JDK5 + 特性)

Java 编译器自动完成装箱 / 拆箱操作,无需手动调用方法,简化代码。

java 复制代码
public class AutoBoxUnboxDemo {
    public static void main(String[] args) {
        // 自动装箱:基本类型→包装类
        Integer num1 = 10;  // 等价于 Integer num1 = Integer.valueOf(10);
        Boolean flag = true;// 等价于 Boolean flag = Boolean.valueOf(true);
        
        // 自动拆箱:包装类→基本类型
        int num2 = num1;    // 等价于 int num2 = num1.intValue();
        boolean b = flag;   // 等价于 boolean b = flag.booleanValue();
        
        // 运算时自动拆箱
        Integer sum = num1 + 20; // num1先拆箱为int,计算后再装箱为Integer
        System.out.println("自动装箱拆箱运算:" + sum);
    }
}
注意点:
  • 包装类对象可能为null,自动拆箱时若对象为null会抛出NullPointerException

    java 复制代码
    Integer nullObj = null;
    int n = nullObj; // 运行时抛出NullPointerException
  • IntegervalueOf()有缓存机制(-128~127),超出范围会创建新对象:

    java 复制代码
    Integer a = 127;
    Integer b = 127;
    System.out.println(a == b); // true(缓存)
    
    Integer c = 128;
    Integer d = 128;
    System.out.println(c == d); // false(新对象)

三、基本类型与字符串转换

3.1 基本类型→字符串

方法 1:拼接空字符串(简单但效率较低)
java 复制代码
int num = 100;
String str1 = num + "";
方法 2:String.valueOf()(推荐,无空指针风险)
java 复制代码
double d = 3.14;
String str2 = String.valueOf(d);
方法 3:包装类的toString()方法
java 复制代码
boolean flag = true;
String str3 = Boolean.toString(flag);

3.2 字符串→基本类型

方法 1:包装类的parseXxx()方法(常用)
java 复制代码
String strNum = "123";
int num = Integer.parseInt(strNum);
double d = Double.parseDouble("3.14");
boolean flag = Boolean.parseBoolean("true");
方法 2:包装类的valueOf()方法(返回包装类,可自动拆箱)
java 复制代码
String strLong = "1000000";
long l = Long.valueOf(strLong); // 自动拆箱为long
注意:

字符串格式不正确会抛出NumberFormatException

java 复制代码
String errStr = "abc";
int errNum = Integer.parseInt(errStr); // 抛出NumberFormatException

四、字符串 String 类

4.1 String 类特性

  • 不可变性:String 对象创建后,其字符序列(底层 char 数组)不可修改,任何修改操作都会生成新的 String 对象。
  • 常量池优化 :字符串字面量(如"abc")会存储在字符串常量池中,相同字面量复用对象,节省内存。

4.2 String 对象创建方式

java 复制代码
public class StringCreateDemo {
    public static void main(String[] args) {
        // 方式1:字面量创建(存储在常量池)
        String s1 = "Hello";
        String s2 = "Hello";
        System.out.println(s1 == s2); // true(常量池复用对象)
        
        // 方式2:new关键字创建(堆内存新对象)
        String s3 = new String("Hello");
        String s4 = new String("Hello");
        System.out.println(s3 == s4); // false(不同对象)
        System.out.println(s3.equals(s4)); // true(内容相同)
        
        // 方式3:拼接创建(编译期优化)
        String s5 = "He" + "llo"; // 编译期优化为"Hello",指向常量池
        System.out.println(s1 == s5); // true
        
        // 变量拼接(运行期创建新对象)
        String a = "He";
        String s6 = a + "llo";
        System.out.println(s1 == s6); // false
    }
}

五、String 常用方法

5.1 获取相关方法

java 复制代码
public class StringMethodDemo1 {
    public static void main(String[] args) {
        String str = "Java进阶笔记";
        
        // 1. length():获取字符串长度
        int len = str.length();
        System.out.println("长度:" + len); // 输出7
        
        // 2. charAt(int index):获取指定索引的字符
        char ch = str.charAt(2);
        System.out.println("索引2的字符:" + ch); // 输出v
        
        // 3. indexOf(String str):查找子串首次出现的索引,无则返回-1
        int index = str.indexOf("进阶");
        System.out.println("进阶首次出现索引:" + index); // 输出4
        
        // 4. lastIndexOf(String str):查找子串最后出现的索引
        String str2 = "ababa";
        int lastIndex = str2.lastIndexOf("aba");
        System.out.println("aba最后出现索引:" + lastIndex); // 输出2
    }
}

5.2 判断相关方法

java 复制代码
public class StringMethodDemo2 {
    public static void main(String[] args) {
        String str = "HelloWorld";
        
        // 1. equals(Object obj):比较内容是否相同(区分大小写)
        boolean eq = str.equals("helloworld");
        System.out.println("equals比较:" + eq); // false
        
        // 2. equalsIgnoreCase(String str):忽略大小写比较
        boolean eqIgnoreCase = str.equalsIgnoreCase("helloworld");
        System.out.println("忽略大小写比较:" + eqIgnoreCase); // true
        
        // 3. contains(CharSequence s):是否包含指定子串
        boolean contains = str.contains("World");
        System.out.println("是否包含World:" + contains); // true
        
        // 4. startsWith(String prefix):是否以指定前缀开头
        boolean start = str.startsWith("Hello");
        System.out.println("是否以Hello开头:" + start); // true
        
        // 5. endsWith(String suffix):是否以指定后缀结尾
        boolean end = str.endsWith("d");
        System.out.println("是否以d结尾:" + end); // true
        
        // 6. isEmpty():是否为空字符串(长度为0)
        boolean empty = "".isEmpty();
        System.out.println("空字符串判断:" + empty); // true
    }
}

5.3 转换相关方法

java 复制代码
public class StringMethodDemo3 {
    public static void main(String[] args) {
        String str = "  Java String  ";
        
        // 1. toUpperCase():转大写
        String upper = str.toUpperCase();
        System.out.println("转大写:" + upper); // 输出"  JAVA STRING  "
        
        // 2. toLowerCase():转小写
        String lower = str.toLowerCase();
        System.out.println("转小写:" + lower); // 输出"  java string  "
        
        // 3. trim():去除首尾空格(JDK11+可用strip(),支持Unicode空白字符)
        String trimStr = str.trim();
        System.out.println("去除首尾空格:[" + trimStr + "]"); // 输出"[Java String]"
        
        // 4. toCharArray():转为字符数组
        char[] chars = "abc".toCharArray();
        System.out.println("字符数组:" + chars[1]); // 输出b
        
        // 5. replace(CharSequence target, CharSequence replacement):替换子串
        String replaceStr = "abac".replace("a", "x");
        System.out.println("替换结果:" + replaceStr); // 输出xbxc
    }
}

5.4 截取与分割方法

java 复制代码
public class StringMethodDemo4 {
    public static void main(String[] args) {
        String str = "Java-进阶-2025-笔记";
        
        // 1. substring(int beginIndex):从指定索引截取到末尾
        String sub1 = str.substring(5);
        System.out.println("截取结果1:" + sub1); // 输出"进阶-2025-笔记"
        
        // 2. substring(int beginIndex, int endIndex):截取[begin,end)区间
        String sub2 = str.substring(5, 7);
        System.out.println("截取结果2:" + sub2); // 输出"进阶"
        
        // 3. split(String regex):按正则分割字符串
        String[] arr = str.split("-");
        for (String s : arr) {
            System.out.print(s + " "); // 输出Java 进阶 2025 笔记
        }
    }
}

六、equals 方法详解

6.1 equals 与 == 的区别

  • ==
    • 比较基本类型:判断值是否相等。
    • 比较引用类型:判断对象地址是否相同(是否为同一个对象)。
  • equals()
    • Object 类中默认实现是==(比较地址)。
    • String 类重写了equals(),改为比较字符序列内容

6.2 String 类 equals 源码解析

java 复制代码
public boolean equals(Object anObject) {
    if (this == anObject) { // 先判断地址,相同则直接返回true
        return true;
    }
    if (anObject instanceof String) { // 判断是否为String类型
        String anotherString = (String)anObject;
        int n = value.length; // value是String底层存储字符的char数组
        if (n == anotherString.value.length) { // 长度相同才继续比较
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) { // 逐字符比较
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

6.3 自定义类重写 equals

若自定义类需要按内容比较,需重写equals()

java 复制代码
class Student {
    private String name;
    private int age;
    
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    // 重写equals,按name和age比较
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age && Objects.equals(name, student.name);
    }
}

public class EqualsDemo {
    public static void main(String[] args) {
        Student s1 = new Student("张三", 20);
        Student s2 = new Student("张三", 20);
        System.out.println(s1 == s2); // false(不同对象)
        System.out.println(s1.equals(s2)); // true(内容相同)
    }
}

七、toString 方法

7.1 toString 作用

返回对象的字符串表示,默认输出 "类名 @哈希码",重写后可输出对象的属性信息,方便调试。

7.2 默认实现与重写

java 复制代码
class Person {
    private String name;
    private int age;
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    // 重写toString方法
    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + "}";
    }
}

public class ToStringDemo {
    public static void main(String[] args) {
        Person p = new Person("李四", 25);
        // 默认toString(未重写):Person@1b6d3586
        // 重写后:Person{name='李四', age=25}
        System.out.println(p); // 等价于System.out.println(p.toString());
    }
}

八、可变字符串(StringBuilder & StringBuffer)

8.1 为什么需要可变字符串

String 是不可变的,频繁拼接会创建大量临时对象,效率低下。可变字符串类(StringBuilder/StringBuffer)支持直接修改字符序列,性能更高。

8.2 StringBuilder 与 StringBuffer 区别

特性 StringBuilder StringBuffer
线程安全 不安全(效率高) 安全(效率低)
适用场景 单线程环境 多线程环境
性能 较慢

8.3 常用方法

java 复制代码
public class StringBuilderDemo {
    public static void main(String[] args) {
        // 创建StringBuilder对象
        StringBuilder sb = new StringBuilder("Java");
        
        // 1. append(...):追加内容
        sb.append("进阶");
        sb.append(2025);
        System.out.println("append后:" + sb); // 输出Java进阶2025
        
        // 2. insert(int offset, ...):插入内容
        sb.insert(4, "-");
        System.out.println("insert后:" + sb); // 输出Java-进阶2025
        
        // 3. replace(int start, int end, String str):替换
        sb.replace(5, 7, "高级");
        System.out.println("replace后:" + sb); // 输出Java-高级2025
        
        // 4. delete(int start, int end):删除
        sb.delete(8, 12);
        System.out.println("delete后:" + sb); // 输出Java-高级
        
        // 5. reverse():反转
        sb.reverse();
        System.out.println("reverse后:" + sb); // 输出级高-avaJ
        
        // 6. 转为String
        String result = sb.toString();
        System.out.println("最终String:" + result);
    }
}

8.4 性能对比(String vs StringBuilder)

java 复制代码
public class PerformanceDemo {
    public static void main(String[] args) {
        // String拼接(低效)
        long start1 = System.currentTimeMillis();
        String s = "";
        for (int i = 0; i < 10000; i++) {
            s += i;
        }
        long end1 = System.currentTimeMillis();
        System.out.println("String拼接耗时:" + (end1 - start1) + "ms");
        
        // StringBuilder拼接(高效)
        long start2 = System.currentTimeMillis();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 10000; i++) {
            sb.append(i);
        }
        long end2 = System.currentTimeMillis();
        System.out.println("StringBuilder拼接耗时:" + (end2 - start2) + "ms");
    }
}

输出示例

复制代码
String拼接耗时:150ms
StringBuilder拼接耗时:1ms

总结

掌握这些知识点,能有效解决开发中的字符串处理、类型转换等高频问题,同时规避常见坑点

  1. 本文覆盖了 Java 进阶中包装类、字符串操作的核心知识点:

  2. 包装类实现基本类型的对象化,自动装箱拆箱简化代码但需注意缓存池和空指针问题;

  3. 基本类型与字符串转换有固定套路,推荐使用String.valueOf()包装类.parseXxx()

  4. String 类不可变,核心方法和equals()toString()是面试重点;

  5. 可变字符串优先使用StringBuilder(单线程),多线程用StringBuffer

相关推荐
U***e631 小时前
Python测试
开发语言·python
四谎真好看2 小时前
Java 黑马程序员学习笔记(进阶篇28)
java·笔记·学习·学习笔记
晨晖22 小时前
springboot的Thymeleaf语法
java·spring boot·后端
yi碗汤园2 小时前
Visual Studio常用的快捷键
开发语言·ide·c#·编辑器·visual studio
p***95002 小时前
【SpringBoot】日志文件
java·spring boot·spring
Elias不吃糖2 小时前
NebulaChat:C++ 高并发聊天室服务端
开发语言·c++·redis·sql·项目文档
b***66612 小时前
【springboot】健康检查 监控
java·spring boot·后端
haofafa2 小时前
JavaScript性能优化实战
开发语言·javascript·性能优化
明洞日记2 小时前
【设计模式手册010】组合模式 - 树形结构的优雅处理
java·设计模式·组合模式