首页
学习
活动
专区
圈层
工具
发布

5年Java竟然不清楚 int(1) 和 int(10) 的区别!

哈哈,这个话题其实挺有意思的,很多人写了好几年 Java,可能都没认真想过int(1)和int(10)到底有什么区别。上次我在群里问了下,十个程序员有八个都答错,剩下两个还犹豫半天。

“int(1)” 是一?不是的兄弟

那天我们公司一个新同事写了个表结构,我一看:

CREATE TABLE user (

id INT(1) NOT NULL,

age INT(10),

PRIMARY KEY (id)

);

我问他:“你这是干嘛?id只允许一位数?” 他一脸理所当然地说:“对啊,int(1)不就是最多一位数嘛?”

其实啊,这就是一个超级常见的误区。 在 MySQL 里(注意,是 MySQL,不是 Java),INT(1)里的(1)根本和取值范围没关系。 它只是显示宽度(display width),也就是说,当你启用ZEROFILL时,它会用 0 补齐显示宽度。

举个例子:

CREATE TABLE num_test (

a INT(1) ZEROFILL,

b INT(10) ZEROFILL

);

INSERT INTO num_test VALUES (1, 1);

SELECT * FROM num_test;

查询结果会是:

a      | b

-------|----------

0      | 0000000001

看到了吧?数值其实都能存一样的范围,只是显示的时候有区别。INT(1)≠ “只能存一位数”,它照样能存 2,147,483,647。

那 Java 里的 int 呢?

再说回我们熟悉的 Java。 Java 里根本没有 int(1) 这种东西,int就是固定 4 个字节,范围是-2,147,483,648 ~ 2,147,483,647。 没有“括号”的说法。

你在 Java 里写:

int a = 1;

int b = 10;

这俩完全没区别,连类型信息都一样。 如果你用包装类Integer去接,也一样,底层都是 32 位二进制数。

真正的坑:数据库 + Java 的交互

问题来了,当数据库是int(1)的时候,Java 取出来到底是什么?

这时候很多人踩坑。 比如有同事在 MyBatis 里写个映射:

而数据库建表是:

is_active TINYINT(1)

他以为(1)代表 boolean。 结果读出来变成了1或0,再自动映射到boolean类型…… 刚好能用,但语义上非常混乱。

正确的做法其实是:

is_active TINYINT(1) DEFAULT 1 COMMENT '是否启用,0=否 1=是'

然后 Java 里定义为:

private boolean active;

或者你用枚举更安全:

public enum Status {

  DISABLED, ENABLED

}

别看(1)好像在暗示布尔值,它其实只是显示宽度的遗留产物。 MySQL 8.0 已经官方移除了INT(M)的显示宽度语义。

我记得有次在做订单系统的时候,表里有个字段叫status INT(2)。 我以为最多两位数,于是写了逻辑:

if (status > 99) {

  throw new IllegalArgumentException("状态值异常");

}

结果上线当天直接报错。 因为运营那边加了个新状态 200——他们以为数据库能放。 结果数据库没问题,Java 报错了…… 根本原因就是对(2)理解错了。

延伸:MySQL 各种 int 类型的取值范围

括号里的数字再大也没用——不会限制取值范围。

所以结论其实很简单:

int(1)和int(10)在 Java 里没区别;

在 MySQL 里也没区别,除非你用了ZEROFILL;

(M)表示显示宽度,而不是取值范围;

MySQL 8 以后已经弃用这个特性;

千万别在代码里靠它控制业务逻辑。

其实我第一次知道这个区别还是因为一个线上 bug。 当时有个接口返回的 JSON 把id显示成"0000000012",前端那边还以为是字符串,结果前端强转失败。 后来才发现是因为ZEROFILL把它补成了 10 位。

有时候啊,这种看起来无关紧要的小细节,真能把你坑到凌晨两点。

  • 发表于:
  • 原文链接https://page.om.qq.com/page/OltBw8zhSMAr5UvBBHnz2OOg0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。
领券