BigInteger和Long的区别

一、场景引入:为什么你的数据库类型会报错?

在Java开发中,你是否遇到过这样的报错:ClassCastException: java.lang.Long cannot be cast to java.math.BigInteger?或者明明数据库的BIGINT字段能存储大数,Java程序却出现数值溢出?这背后其实隐藏着BigInteger与Long的核心差异。本文将通过3分钟快速解读,让你彻底掌握两者的区别,并解决数据库字段类型映射的选型难题。

二、BigInteger vs Long:核心差异对比

1. 数值范围

Long:64位有符号整数,范围是 -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807,超出范围会自动溢出导致结果错误。

BigInteger:任意精度整数,无固定范围限制(仅受内存限制),可精确计算超大数(如1000的阶乘)

示例对比:计算100的阶乘
用Long:直接溢出为负数
用BigInteger:正确输出933262154439891732384626...(共158位)

2. 性能与存储方式的差异

特性

Long

BigInteger

存储方式

栈内存直接存储(8字节)

堆内存对象(动态int数组)

运算速度

快(CPU原生支持)

慢(需模拟大数运算)

运算符支持

支持+-*等运算符

必须调用add()multiply()等方法

三、数据库BIGINT字段选型指南

1. 必须选Long的情况

当数据库字段为 BIGINT(有符号) 时,其范围与Java的Long完全一致。此时优先使用Long,性能更高且无转换问题。

MyBatis映射示例

public class User {
    private Long id;  // 对应数据库BIGINT字段
}

2. 必须选BigInteger的情况

当数据库字段为 BIGINT UNSIGNED(无符号) 时,其范围是 0 ~ 18,446,744,073,709,551,615,超过Long的正数上限。此时必须用BigInteger,否则会溢出或转换异常。

错误示范

// 错误!BIGINT UNSIGNED超过Long范围
private Long id;  
// 正确写法:
private BigInteger id;

四、开发避坑指南

1. ORM框架映射规则

  • MyBatis/MyBatis-Plus:根据数据库字段符号类型自动映射:
    • BIGINT → Long
    • BIGINT UNSIGNED → BigInteger

强制类型错误:若用Long接收无符号BIGINT,会触发ClassCastException

2. 性能优化建议

避免滥用BigInteger:仅在大数计算时使用,常规场景用Long效率提升百倍

  • 数值边界检查:通过DESCRIBE命令确认数据库字段是否为无符号:
DESCRIBE your_table;  -- 查看字段是否有UNSIGNED标识

五、总结对比表

对比维度

Long

BigInteger

范围

-9,223,372,036,854,775,808 至 9,223,372,036,854,775,807

无限(受内存限制)

性能

溢出处理

自动回绕(可能导致错误)

精确计算无溢出

适用场景

时间戳、常规ID

加密算法、科学计算、超大数

数据库映射

BIGINT(有符号)

BIGINT UNSIGNED

六、实战口诀

“有符号选Long,无符号用BigInteger;性能优先看场景,超大计算不犹豫”。合理选择类型,既能避免程序崩溃,又能提升运行效率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值