摘要:面试的时候,面试官问:“如果你要在 Java 里存电话号码,你会用 int 还是 String?”
大家有没有遇到过这种情况?
面试的时候,面试官问:“如果你要在 Java 里存电话号码,你会用 int 还是 String?”
如果你脑子一抽,回答“int”,那基本就可以和这个 offer 说再见了。
电话号码存储问题,看似简单,其实是个大坑!
今天我们就来深扒一下,为什么用 int 存储电话号码是个大坑,为什么 String 才是最优解。
一般来说,Java 里存电话号码有两种方式:
int:基本数据类型,占 4 字节(32 位),用于存整数。String:引用数据类型,可以存储任何字符序列。你可能会想:“电话号码不就是一串数字吗?用 int 存不是更节省内存?”
然鹅,事实并非如此!
你可能觉得电话号码就是一串数字,应该用 int,但我们要先搞清楚:
电话号码是“标识符”,而不是数值!
为什么这么说?因为电话号码不会进行数学运算,你不会拿两个手机号相加求和吧?
更重要的是,电话号码可能包含:
国际区号(+86、+1)分隔符(-、空格)分机号(1234 ext. 567)如果你用 int 存,比如:
int phoneNumber = 8613812345678;恭喜你,国际区号 +86 已经丢失了。
而且 Java 的 int 最大值是 2^31 - 1,也就是 2147483647,你存个美国的电话号码 15551234567 都会溢出,更别提国际号码了。
如果你想用 long:
long phoneNumber = 15551234567890L;虽然可以存更长的数字,但依然无法存储 +、-,更别提扩展号(ext.)了。
明白了 int 的坑,我们看看 String 有什么优势。
String phoneNumber = "+86 138 1234 5678";可以存 + 和 -,不会丢失信息。不会溢出,国际号码随便存。易读易解析,比如做正则校验、格式化。数据库友好,存入 MySQL 时 VARCHAR 直接存,不用转换。可以存分机号,适用于企业通讯录。你可能担心 String 会浪费内存?
其实 Java 里 String 有字符串常量池优化,重复字符串不会创建多个对象。对于大量重复的电话号码,内存占用并不比 int 高多少。
如果你真的在意内存,可以用 intern 方法手动优化:
String phoneNumber = new String("+86 138 1234 5678").intern;这样 JVM 只存一份,减少内存开销。
此外,你还可以使用 StringBuilder 拼接字符串,避免创建过多 String 对象:
StringBuilder phoneNumber = new StringBuilder;phoneNumber.append("+86").append(" 138 1234 5678");从 JVM 角度来看:
int 操作简单,比如加法 iadd,速度快。String 操作涉及 new、invokespecial(构造方法调用),相对复杂。但是!电话号码根本不会进行数学运算,所以 int 的性能优势根本没有用武之地!
此外,现代 JVM 已经对 String 进行了大量优化,比如垃圾回收(GC)会优化字符串存储,所以担心 String 开销的同学可以放心了。
国际号码存不了,用户投诉。数据丢失,区号 +1 被误认为 1,美国号码和中国号码混在一起。无法存分机号,导致企业用户无法正常使用。后来不得不迁移到 String,付出了巨大的数据迁移成本。最终,他们乖乖用 String 存电话号码,才彻底解决问题。
✅ String 能存 +、-,不会丢失信息。✅ 不会溢出,适用于国际号码。✅ 数据库存储友好,不用做复杂转换。✅ JVM 优化好,性能不会差太多。✅ 适用于企业通讯录,可存扩展号。✅ 易于格式化、正则校验,适配各种业务需求。
来源:散文随风想