### Java编程中那些意想不到的代码陷阱与解决方案
#### 1. 浮点数精度问题
陷阱示例:
```java
System.out.println(0.1 + 0.2); // 输出:0.30000000000000004
```
解决方案:
- 使用BigDecimal进行精确计算
```java
BigDecimal a = new BigDecimal(0.1);
BigDecimal b = new BigDecimal(0.2);
System.out.println(a.add(b)); // 输出:0.3
```
#### 2. 字符串比较的坑
陷阱示例:
```java
String s1 = new String(hello);
String s2 = hello;
System.out.println(s1 == s2); // 输出:false
```
解决方案:
- 始终使用equals方法比较字符串
```java
System.out.println(s1.equals(s2)); // 输出:true
```
#### 3. 自动装箱拆箱的NPE
陷阱示例:
```java
Integer num = null;
int value = num; // 抛出NullPointerException
```
解决方案:
- 对可能为null的包装类型进行判空
```java
Integer num = null;
int value = num != null ? num : 0;
```
#### 4. 循环中的集合修改异常
陷阱示例:
```java
List list = new ArrayList<>(Arrays.asList(a, b, c));
for (String s : list) {
if (b.equals(s)) {
list.remove(s); // 抛出ConcurrentModificationException
}
}
```
解决方案:
- 使用迭代器的remove方法
```java
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
String s = iterator.next();
if (b.equals(s)) {
iterator.remove();
}
}
```
#### 5. 日期时间处理的陷阱
陷阱示例:
```java
// 月份从0开始
Calendar cal = Calendar.getInstance();
cal.set(2023, 0, 1); // 实际设置的是1月1日
```
解决方案:
- 使用Java 8的新日期时间API
```java
LocalDate date = LocalDate.of(2023, 1, 1); // 明确表示1月1日
```
#### 6. finally块中的return覆盖
陷阱示例:
```java
public int test() {
try {
return 1;
} finally {
return 2; // 实际返回2,覆盖了try中的返回值
}
}
```
解决方案:
- 避免在finally块中使用return
```java
public int test() {
int result = 0;
try {
result = 1;
} finally {
// 只进行清理操作
}
return result;
}
```
#### 7. 静态变量的初始化顺序
陷阱示例:
```java
class Test {
static {
value = 10; // 编译错误
}
static int value;
}
```
解决方案:
- 合理安排静态变量的声明和初始化顺序
```java
class Test {
static int value;
static {
value = 10; // 正确
}
}
```
#### 8. 重写equals但不重写hashCode
陷阱示例:
```java
class Person {
String name;
@Override
public boolean equals(Object obj) {
// 实现equals但不重写hashCode
}
}
// 在HashSet中会出现异常行为
```
解决方案:
- 同时重写equals和hashCode方法
```java
@Override
public int hashCode() {
return Objects.hash(name);
}
```
#### 9. 资源未正确关闭
陷阱示例:
```java
FileInputStream fis = new FileInputStream(file.txt);
// 使用后忘记关闭
```
解决方案:
- 使用try-with-resources
```java
try (FileInputStream fis = new FileInputStream(file.txt)) {
// 使用资源
} // 自动关闭
```
#### 10. 不可变对象的修改陷阱
陷阱示例:
```java
List list = Arrays.asList(a, b, c);
list.add(d); // 抛出UnsupportedOperationException
```
解决方案:
- 创建可修改的副本
```java
List list = new ArrayList<>(Arrays.asList(a, b, c));
list.add(d); // 正常执行
```
这些陷阱往往源于对Java语言特性的理解不足或疏忽。通过了解这些常见问题及其解决方案,开发者可以编写出更加健壮和可靠的Java代码。在实际开发中,建议结合代码审查、单元测试和静态代码分析工具来进一步避免这些陷阱。
957

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



