文章目录
Java API是提升开发效率的关键武器,本文将全面解析Object类、包装类、字符串处理工具等核心API的使用技巧与底层原理
一、API概述与学习路径
API(应用程序编程接口) 是Java预先编写好的程序模块(类、方法等),开发者可直接调用解决特定问题。Java进阶需掌握以下核心API:

今天学习的内容:
学习建议:
- 理解每个API的设计目的
- 掌握关键方法的使用场景
- 通过实践对比不同API的性能差异
- 善用IDE的源码查看功能(Ctrl+点击类名)
二、Object类:Java的祖宗类
作为所有类的超类,Java中所有类的对象都可以直接使用Object类中提供的一些方法:

1. toString()方法
作用:返回对象的字符串表示形式
toString()方法存在的意义就是为了被子类重写,以便返回对象具体的内容。
// 默认实现
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
// 正确实践:重写示例
@Override
public String toString() {
return "Student{name='" + name + "', age=" + age + "}";
}
开发规范:
- 所有实体类必须重写toString()
- 输出内容应包含关键属性值
- 避免在方法内进行复杂计算
2. equals()方法
作用:比较对象是否相等
直接比较两个对象的地址是否相同完全可以用“==”替代equals,equals存在的意义就是为了被子类重写,以便子类自己来定制比较规则(比如比较对象内容)。
// 默认实现(等价于==)
public boolean equals(Object obj) {
return (this == obj);
}
// 正确重写步骤:
@Override
public boolean equals(Object o) {
// 1. 地址相同直接返回true
if (this == o) return true;
// 2. 处理null和类型不匹配
if (o == null || getClass() != o.getClass()) return false;
// 3. 类型转换后比较字段值
Student student = (Student) o;
return age == student.age &&
Objects.equals(name, student.name);
}
// 可以使用Alt+Insert选择生成equals()和hashCode()
@Override
public int hashCode() {
return Objects.hash(name, age);
}
关键点:
- 重写equals()必须同时重写hashCode()
- 比较逻辑应满足自反性、对称性、传递性
- 优先使用Objects.equals()比较可能为null的属性
3. clone()方法(了解)
当某个对象调用这个方法时,这个方法会复制一个一模一样的新对象返回。
对象克隆的两种实现方式:
| 克隆类型 | 特点 | 实现方式 |
|---|---|---|
| 浅克隆 | 引用类型字段共享地址 | super.clone() |
| 深克隆 | 完全独立的对象副本 | 递归调用clone() |
// 深克隆实现
@Override
protected Object clone() throws CloneNotSupportedException {
User cloned = (User) super.clone();
cloned.scores = scores.clone(); // 数组深拷贝
return cloned;
}
内存示意图:
浅克隆:
原对象 --> [基本类型值]
[引用类型地址] --> 共享数据
深克隆:
原对象 --> [基本类型值]
[新引用地址] --> 独立数据副本

三、Objects工具类

可以用s1.equals(s2) 和 Objects.equals(s1,s2) 判断是否相等,那为什么idea自动创建equals 方法重写时用 Objects.equals(name, student.name) 呢?
解决对象操作中的空指针问题:
// 安全比较(自动处理null)
Objects.equals(null, "test"); // false
null equals("test") //会报错,不安全,不好用
// 空检查
Objects.isNull(obj); // 替代 obj == null
Objects.nonNull(obj); // 替代 obj != null
// 源码解析
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
使用场景:
- 方法参数校验
- 避免级联null检查
- 比较用户输入等不可控对象

四、包装类:基本类型的对象化
1. 包装类体系
| 基本类型 | 包装类 | 缓存范围 |
|---|---|---|
| byte | Byte | -128~127 |
| short | Short | -128~127 |
| int | Integer | -128~127 |
| long | Long | -128~127 |
| float | Float | 无缓存 |
| double | Double | 无缓存 |
| char | Character | 0~127 |
| boolean | Boolean | true/false |
2. 自动装箱/拆箱
// 自动装箱(编译器优化)
Integer a = 100;
// 等价于→ Integer.valueOf(100)
// 自动拆箱
int b = a;
// 等价于→ a.intValue()
注意事项:
- 包装类对象不可变(修改值会创建新对象)
- 数值比较使用equals()而非==
- 警惕NPE:
Integer num = null; int n = num; // 抛出NullPointerException
3. 类型转换
// String → 基本类型
int age = Integer.parseInt("25");
double score = Double.parseDouble("89.5");
// 基本类型 → String
String s1 = Integer.toString(100);
String s2 = String.valueOf(3.14f);
String s3 = 200 + ""; // 不推荐(产生临时对象)

五、高性能字符串处理
1. StringBuilder vs String

性能对比实验:
// 错误示范:字符串拼接
String result = "";
for (int i = 0; i < 100000; i++) {
result += "a"; // 每次循环创建新对象
}
// 正确做法
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 100000; i++) {
sb.append("a"); // 修改内部char[]
}
return sb.toString();
性能差异:
- 10万次拼接:StringBuilder约5ms vs String约8秒
- 原因:String不可变性导致大量临时对象
对于字符串相关的操作,如频繁的拼接、修改等,建议用StringBuidler,效率更高!
注意:如果操作字符串较少,或者不需要操作,以及定义字符串变量,还是建议用String。
2. StringBuilder核心API
// 链式调用
sb.append("Hello")
.append(" ")
.append("World!")
.insert(5, ",")
.reverse();
// 容量管理
sb.ensureCapacity(100); // 预分配空间
sb.trimToSize(); // 释放多余空间

3. StringBuffer线程安全版
StringBuffer的用法与StringBuilder是一模一样的
// 用法相同但线程安全
StringBuffer safeBuffer = new StringBuffer();
safeBuffer.append("Thread-Safe");
// 实现原理
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
选型建议:
- 单线程环境:StringBuilder(速度更快)
- 多线程环境:StringBuffer(线程安全)
- 少量操作:String(代码简洁)
六、StringJoiner:结构化拼接
JDK8提供的增强型字符串工具:跟StringBuilder一样,也是用来操作字符串的,也可以看成是一个容器,创建之后里面的内容是可变的。
好处:不仅能提高字符串的操作效率,并且在有些场景下使用它操作字符串,代码会更简洁
用法:
public StringJoiner (间隔符号)
public StringJoiner (间隔符号,开始符号,结束符号)
// 基础用法
StringJoiner sj = new StringJoiner(", ", "[", "]");
sj.add("Apple").add("Orange").add("Banana");
// 输出:[Apple, Orange, Banana]
// 替代StringBuilder的集合拼接
List<String> list = Arrays.asList("Java", "Python", "C++");
String result = String.join("|", list); // Java|Python|C++
优势场景:
- CSV文件生成
- SQL IN条件拼接
- JSON数组构造
- 带前缀后缀的格式化输出
七、实战应用案例
1. 对象比较工具
public static boolean safeEquals(Object a, Object b) {
return Objects.equals(a, b);
}
2. 数组格式化输出
public static String formatArray(int[] arr) {
if (arr == null) return "null";
StringJoiner sj = new StringJoiner(", ", "[", "]");
for (int num : arr) {
sj.add(String.valueOf(num));
}
return sj.toString();
}
3. 深克隆工具方法
public static <T extends Serializable> T deepClone(T obj) {
try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos)) {
oos.writeObject(obj);
try (ByteArrayInputStream bis =
new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis)) {
return (T) ois.readObject();
}
} catch (Exception e) {
throw new RuntimeException("Clone failed", e);
}
}
八、总结与最佳实践
-
Object类:
- 重写toString()提供可读信息
- 重写equals()/hashCode()保证对象比较正确性
- 慎用clone(),优先考虑复制构造器
-
包装类:
- 集合存储必须使用包装类
- 数值比较用equals()而非==
- 注意自动装箱的性能开销
-
字符串处理:
- 循环内拼接必须用StringBuilder
- 预分配容量(new StringBuilder(500))
- 复杂格式化使用StringJoiner
-
性能陷阱规避:
// 反面示例 String str = "Start"; for (Data item : bigList) { str += item; // 产生大量临时对象 } // 正面示例 StringBuilder sb = new StringBuilder(1024); sb.append("Start"); for (Data item : bigList) { sb.append(item); }
掌握这些核心API的使用哲学,将使你的Java代码更加健壮高效。记住:正确的API选择比盲目优化代码更重要!
:Object、包装类、字符串处理&spm=1001.2101.3001.5002&articleId=148923721&d=1&t=3&u=8b7400b48bc943a2a0f7784267997293)
1281

被折叠的 条评论
为什么被折叠?



