# Java编程中的反直觉陷阱:为什么看似正确的代码会产生意外结果?
## 浮点数精度问题
```java
System.out.println(0.1 + 0.2 == 0.3); // 输出false
```
这个看似简单的加法比较却返回false,因为浮点数在计算机中是以二进制形式存储的,0.1和0.2在二进制中是无限循环小数,存在精度损失。
## 字符串比较陷阱
```java
String s1 = hello;
String s2 = new String(hello);
System.out.println(s1 == s2); // 输出false
System.out.println(s1.equals(s2)); // 输出true
```
使用==比较字符串实际上比较的是对象引用,而非内容。新手程序员常常误用==来比较字符串内容。
## 整数溢出问题
```java
int max = Integer.MAX_VALUE;
int result = max + 1;
System.out.println(result); // 输出-2147483648
```
整数运算不会抛出异常,而是会默默溢出,这可能导致计算结果与预期完全不符。
## 空指针异常隐藏
```java
public boolean isLongString(String str) {
return str.length() > 10;
}
```
当传入null时,这个方法会抛出NullPointerException,但代码本身看起来完全正确。
## 集合修改异常
```java
List list = new ArrayList<>(Arrays.asList(a, b, c));
for (String item : list) {
if (b.equals(item)) {
list.remove(item); // 可能抛出ConcurrentModificationException
}
}
```
在遍历集合时修改集合内容会导致ConcurrentModificationException,即使逻辑上看起来合理。
## 日期时间处理陷阱
```java
Calendar cal = Calendar.getInstance();
cal.set(Calendar.MONTH, Calendar.JANUARY);
cal.set(Calendar.DATE, 31);
cal.set(Calendar.MONTH, Calendar.FEBRUARY);
System.out.println(cal.get(Calendar.DATE)); // 输出结果可能令人惊讶
```
当设置不存在的日期(如2月31日)时,Calendar会自动调整日期,这可能产生意想不到的结果。
## 自动装箱空指针
```java
Integer i = null;
int j = i; // 抛出NullPointerException
```
自动拆箱时,如果包装类对象为null,会抛出NullPointerException,这在代码中并不明显。
## 避免陷阱的建议
1. 使用BigDecimal进行精确的金融计算
2. 始终使用equals()方法比较字符串内容
3. 检查数学运算的边界条件,防止溢出
4. 对可能为null的参数进行显式检查
5. 使用迭代器或流API安全地修改集合
6. 优先使用java.time包处理日期时间
7. 注意自动装箱拆箱的潜在风险
理解这些反直觉的陷阱有助于编写更健壮、可靠的Java代码,减少潜在的bug和意外行为。
11万+

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



