0赞
赞赏
更多好文
别让Java数据类型坑了你:一个被“int”逼到崩溃的程序员手记
上周三,我盯着屏幕,手抖得差点把咖啡泼在键盘上。
用户输入“10000000000”(十亿),系统返回“-1410065408”。
不是代码写错了——是int溢出了。
这破事,我干过第7次了。
今天不扯理论,只说点血淋淋的实战经验。
一、基本数据类型:别被“默认”骗了
Java的8种基本类型,别信网上说的“int能存20亿”。
真实情况是:
int最大值是 2,147,483,647(21亿),超了就变负数。
去年有个订单系统,用int存订单ID,结果第2147483648单直接报错——不是系统崩了,是数据类型没选对。
| 类型 | 范围 | 陷阱案例 |
|---|---|---|
int | -21亿 ~ +21亿 | 10亿+1 → 负数(如上例) |
long | -9e18 ~ +9e18 | 用long存大数(比如用户ID) |
float | 精度差,≈7位小数 | 0.1 + 0.2 != 0.3(真·坑) |
double | 精度稍好,≈15位小数 | 但别用它算钱! |
血泪教训:
float a = 0.1f; float b = 0.2f; System.out.println(a + b == 0.3f); // 输出 false!为什么?
0.1在二进制里是无限循环小数。
财务计算?直接用BigDecimal,别赌float的命。
二、包装类(Integer, Double...):==是魔鬼
Integer和int傻傻分不清?
记住:==比较的是内存地址,不是值!
我见过团队把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()。
三、运算符:别让“简单”害死你
1. == vs .equals()
==:基本类型比较值,对象比较地址。.equals():必须重写(比如String、Integer都重写了)。
别用==比较字符串!
String s1 = "hello";
String s2 = new String("hello");
System.out.println(s1 == s2); // false
System.out.println(s1.equals(s2)); // true
2. 位运算符:别乱用,除非你懂
&(与)、|(或)、^(异或)在权限判断里超实用,但容易写错:
int role = 1; // 0001
int permission = 2; // 0010
if ((role & permission) != 0) {
// 0001 & 0010 = 0000 → 不走
}
正确用法:
int ADMIN = 1; // 0001
int EDIT = 2; // 0010
int userRole = 3; // 0011(有ADMIN和EDIT权限)
if ((userRole & ADMIN) != 0) { /* 有管理员权限 */ }
if ((userRole & EDIT) != 0) { /* 有编辑权限 */ }
3. 三元运算符:小心类型陷阱
int a = 10;
int b = 20;
Object result = (a > b) ? "a" : 100; // 编译通过!
问题:"a"是String,100是int,三元运算符会自动转成Object。
后果:你可能想result.toString(),结果100变成"100"——但"a"还是"a",逻辑乱了。
建议:别用三元运算符混用不同类型,用if-else更安全。
四、避坑清单:我踩过的坑(别再犯)
-
用
int存用户ID → 溢出。
解法:ID用long(尤其用户量大时)。 -
Integer用==比较 → 逻辑错误。
解法:if (userLevel.equals(1))。 -
float算钱 → 0.1+0.2=0.30000000000000004。
解法:BigDecimal,别省那点内存。 -
String用==→ 用户名比对失败。
解法:永远用.equals()。 -
三元运算符混用类型 → 类型不一致导致逻辑崩。
解法:拆成if-else。
最后一句大实话
数据类型不是选“最小的”,是选“不会让你半夜爬起来修bug的”。
别为了“省内存”用int存金额,也别为了“酷”用float算钱。
上周那个十亿ID的坑,我修了2小时——
代码写得再漂亮,数据类型错了,全是废代码。
行动建议:
- 新项目:金额用
BigDecimal,ID用long,别用int。 - 老代码:全搜
==比较对象,替换成.equals()。 - 位运算?先问自己:“我确定要玩这个吗?”(别玩,除非你懂)。
数据类型是Java的命根子,别让它在你手里变成“坑”。
—— 一个被int坑到怀疑人生的Java老手
