0赞
赞赏
更多好文
上周五,我盯着屏幕,手抖得差点把咖啡泼在键盘上。
用户输入"10000000000"(十亿),系统返回"-1410065408"。不是代码写错了——是int溢出了。这破事,我干过第7次了。
这不是个例。我见过太多团队,为了"省内存"用int存ID,结果第2147483648单直接报错;为了"方便"用float算钱,结果0.1+0.2=0.30000000000000004;甚至有人用==比较Integer,结果用户权限乱了。
今天不扯理论,只说点血淋淋的实战经验。
一、别让"默认类型"坑了你
Java的默认类型陷阱,比你想象的多。
1. int不是万能的
int max = Integer.MAX_VALUE; // 2147483647
int overflow = max + 1; // 结果是-2147483648(溢出!)
真实案例:去年有个电商项目,用int存订单ID,结果第2147483648单直接报错。不是系统崩了,是数据类型没选对。
解决方案:
- ID、金额等大数,直接用
long(long id = 10000000000L)- 金额计算,永远用
BigDecimal(别信float的命)
2. float是魔鬼
float a = 0.1f;
float b = 0.2f;
System.out.println(a + b == 0.3f); // 输出 false!
真实案例:财务系统用float算钱,结果月底对账差了12.34元。不是系统bug,是浮点精度问题。
解决方案:
BigDecimal a = new BigDecimal("0.1"); BigDecimal b = new BigDecimal("0.2"); BigDecimal sum = a.add(b); // 0.3
二、包装类(Integer, Double...):==是魔鬼
Integer和int傻傻分不清?记住:==比较的是内存地址,不是值!
Integer a = 127;
Integer b = 127;
System.out.println(a == b); // true(缓存范围-128~127)
Integer c = 128;
Integer d = 128;
System.out.println(c == d); // false(超出缓存,新建对象)
真实案例:登录接口用Integer存用户等级:
if (userLevel == 1) { ... } // 1是int,userLevel是Integer
结果:用户等级=1时,if不走!因为1是int,userLevel是对象,==比较的是地址。
解决方案:
- 要么全用
int,要么用.equals()if (userLevel.equals(1)) { ... } // 正确
三、字符串与数字:别让"18岁"坑了你
1. 字符串转数字的陷阱
String s = "18岁";
int num = Integer.parseInt(s); // 抛出NumberFormatException
真实案例:用户输入"18岁",系统报错。不是前端没做验证,是后端没处理。
解决方案:
try { int age = Integer.parseInt(s.replaceAll("[^0-9]", "")); } catch (NumberFormatException e) { // 处理错误 }
2. char和String的混淆
char c = "a"; // 编译错误!
char c = 'a'; // 正确
真实案例:新手写char c = "a";,编译直接报错,看了半小时才明白。
解决方案:
char用单引号:char c = 'a';String用双引号:String s = "a";- 如果要从字符串取第一个字符:
char c = s.charAt(0);
四、类型检查:别等异常抛了才后悔
1. 用instanceof提前检查
if (obj instanceof Integer) {
int num = (Integer) obj;
} else {
throw new IllegalArgumentException("必须是整数");
}
2. 避免==比较对象
// 错误
if (userLevel == 1) { ... }
// 正确
if (userLevel != null && userLevel.equals(1)) { ... }
五、实战避坑清单:我踩过的坑(别再犯)
-
用
int存ID → 溢出。
解法:ID用long(尤其用户量大时)。 -
Integer用==比较 → 逻辑错误。
解法:if (userLevel != null && userLevel.equals(1))。 -
float算钱 → 0.1+0.2=0.30000000000000004。
解法:BigDecimal,别赌float的命。 -
String用==→ 用户名比对失败。
解法:永远用.equals()。 -
字符串转数字没处理异常 → 用户输入"abc",系统崩了。
解法:try-catch+ 正则表达式预校验。 -
char和String混用 → 编译直接报错。
解法:记住单引号是char,双引号是String。
最后一句大实话
数据类型不是选"最小的",是选"不会让你半夜爬起来修bug的"。
别为了"省内存"用int存金额,也别为了"酷"用float算钱。上周那个十亿ID的坑,我修了2小时——代码写得再漂亮,数据类型错了,全是废代码。
行动建议:
- 新项目:金额用
BigDecimal,ID用long,别用int。 - 老代码:全搜
==比较对象,替换成.equals()。 - 输入处理:前端表单验证 + 后端
try-catch双重保险。 - 用
instanceof提前检查类型,别等异常抛了才后悔。
数据类型是Java的命根子,别让它在你手里变成"坑"。
—— 一个被int坑到怀疑人生的Java老手
