别让Java数据类型坑了你:一个被NPE追着跑的程序员的血泪总结

avatar
莫雨IP属地:上海
02026-02-16:22:36:21字数 2766阅读 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、金额等大数,直接用longlong 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...):==是魔鬼

Integerint傻傻分不清?记住:==比较的是内存地址,不是值!

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. charString的混淆

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)) { ... }

五、实战避坑清单:我踩过的坑(别再犯)

  1. int存ID → 溢出。
    解法:ID用long(尤其用户量大时)。

  2. Integer==比较 → 逻辑错误。
    解法if (userLevel != null && userLevel.equals(1))

  3. float算钱 → 0.1+0.2=0.30000000000000004。
    解法BigDecimal,别赌float的命。

  4. String== → 用户名比对失败。
    解法:永远用.equals()

  5. 字符串转数字没处理异常 → 用户输入"abc",系统崩了。
    解法try-catch + 正则表达式预校验。

  6. charString混用 → 编译直接报错。
    解法:记住单引号是char,双引号是String


最后一句大实话

数据类型不是选"最小的",是选"不会让你半夜爬起来修bug的"

别为了"省内存"用int存金额,也别为了"酷"用float算钱。上周那个十亿ID的坑,我修了2小时——代码写得再漂亮,数据类型错了,全是废代码


行动建议

  1. 新项目:金额用BigDecimal,ID用long,别用int
  2. 老代码:全搜==比较对象,替换成.equals()
  3. 输入处理:前端表单验证 + 后端try-catch双重保险。
  4. instanceof提前检查类型,别等异常抛了才后悔。

数据类型是Java的命根子,别让它在你手里变成"坑"。
—— 一个被int坑到怀疑人生的Java老手

总资产 0
暂无其他文章

热门文章

暂无热门文章