
Java八大基本类型对应哪些字节和数值边界
Java里每个基本类型都严格规定了占用字节数和取值范围,不是凭感觉记的。比如int固定4字节、long固定8字节,跟运行环境无关——这点和C/C++不同,JVM规范强制统一。
容易错的是把char当成“字符类型”就忽略它本质是无符号16位整数(0~65535),或者误以为boolean占1字节(实际JVM没规定存储大小,数组里用byte模拟,单个变量由具体实现决定)。
-
byte:1字节,-128 ~ 127 -
short:2字节,-32768 ~ 32767 -
int:4字节,-2³¹ ~ 2³¹-1(即 -2147483648 ~ 2147483647) -
long:8字节,-2⁶³ ~ 2⁶³-1 -
float:4字节,IEEE 754 单精度,约±3.4×10³⁸,精度约6~7位十进制数字 -
double:8字节,IEEE 754 双精度,约±1.8×10³⁰⁸,精度约15位 -
char:2字节,0 ~ 65535(即'\u0000' ~ '\uffff') -
boolean:无明确定义大小,仅允许true/false
为什么不能用==比较float和double的精确值
浮点数在二进制中无法精确表示大部分十进制小数,比如0.1 + 0.2 != 0.3是必然结果,不是bug。JVM严格遵循IEEE 754标准,所有语言都面临这个问题,但Java没提供默认容差比较。
常见错误是写if (f == 0.1f)或while (d != 1.0),尤其在循环计数或阈值判断时出问题。
立即学习“Java免费学习笔记(深入)”;
- 用
Math.abs(a - b) 代替<code>==,epsilon按场景选(如1e-6适合float,1e-10适合double) - 金融计算必须用
BigDecimal,别碰float/double - 注意
Float.compare()和Double.compare()能正确处理NaN和±0,比==安全
Integer缓存机制让==有时成立,有时不成立
Integer等包装类有自动缓存(-128~127),所以Integer a = 100; Integer b = 100; a == b返回true;但Integer c = 200; Integer d = 200; c == d就是false——因为超出缓存范围,新建了两个对象。
这个坑常出现在参数传递、集合取值、JSON反序列化后比较时,表面看值一样,==却失效。
- 永远用
.equals()比较包装类值,除非你明确知道在用缓存且范围可控 -
Integer.valueOf(100)走缓存,new Integer(100)一定新建对象(已废弃) - 缓存范围可通过
-XX:AutoBoxCacheMax调大,但不解决根本问题
基本类型在内存中的实际布局影响性能
基本类型变量直接存在栈上(局部变量)或对象内联(成员变量),没有对象头、GC压力小。但一旦装箱成Integer,就变成堆上对象,带来分配开销和GC负担。
高频场景如循环累加、集合遍历、数学计算中滥用包装类,性能可能差几倍。Android上还容易触发频繁GC导致卡顿。
- 优先用
int而非Integer做计算,只在需要泛型(如ArrayList<integer></integer>)或null语义时才装箱 - 避免在
for循环里写list.get(i).intValue()反复拆箱,提前提取到局部变量 - 数组用基本类型(
int[])比对象数组(Integer[])省内存、缓存友好
边界值、浮点误差、缓存陷阱、内存布局——这四个地方踩一个,就可能让看似简单的类型行为变得不可预测。










