常见 Java 问题与排错思路
理解常见问题和排错方法是解决实际开发问题的关键。本章将介绍常见 Java 问题与排错思路。
常见异常类型
NullPointerException
空指针异常是最常见的异常。
// 问题代码
String str = null;
int length = str.length(); // NullPointerException
// 解决方法
// 1. 检查 null
if (str != null) {
int length = str.length();
}
// 2. 使用 Optional
Optional<String> optional = Optional.ofNullable(str);
optional.ifPresent(s -> System.out.println(s.length()));
// 3. 使用 Objects.requireNonNull
String str2 = Objects.requireNonNull(str, "字符串不能为null");
ClassCastException
类型转换异常。
// 问题代码
Object obj = "Hello";
Integer num = (Integer) obj; // ClassCastException
// 解决方法
// 1. 使用 instanceof 检查
if (obj instanceof Integer) {
Integer num = (Integer) obj;
}
// 2. 使用泛型
List<String> list = new ArrayList<>();
// 编译时类型安全
并发问题与死锁
并发问题
// 问题:线程不安全
public class Counter {
private int count = 0;
public void increment() {
count++; // 非原子操作
}
}
// 解决方法
// 1. 使用 synchronized
public synchronized void increment() {
count++;
}
// 2. 使用原子类
private AtomicInteger count = new AtomicInteger(0);
public void increment() {
count.incrementAndGet();
}
死锁
// 问题:死锁
Thread thread1 = new Thread(() -> {
synchronized (lock1) {
synchronized (lock2) { }
}
});
Thread thread2 = new Thread(() -> {
synchronized (lock2) {
synchronized (lock1) { } // 可能死锁
}
});
// 解决方法:按相同顺序获取锁
Thread thread2 = new Thread(() -> {
synchronized (lock1) { // 相同顺序
synchronized (lock2) { }
}
});
调试与日志分析
使用调试器
// 设置断点
public void processData(String data) {
int length = data.length(); // 断点
String processed = process(data);
System.out.println(processed);
}