Java 类型转换,往深了说,是 JVM 底层的一套数据搬运规则。它不仅仅是语法层面的包装,而是直接决定了运算结果的对错、内存布局的形态以及程序能跑多稳。如果不把这条逻辑链条捋清楚,写出来的代码随时可能出幺蛾子。

Java 的类型转换可不是什么语法糖,它是强类型语言背后的底层机制。它直接影响运算结果、内存行为以及整个程序的健壮性。因此,关键不是死记硬背那些转换表格,而是得真琢磨透背后的规则。
自动转换:安全,但暗藏隐式提升
小范围类型往大范围类型赋值时,编译器会默默地帮你完成,数据也不会有任何丢失。不过,真正执行起来,有些细节得心里有数:
- byte、short、char 在做算术运算的时候,会先“偷偷”提升为 int,然后才按表达式里最高的类型继续往上提。
- 比如
byte a = 10; byte b = 20; int c = a + b;,a 和 b 可不是直接相加,而是各自转成 int 再去算。 - char 转成 int,本质上是按 Unicode 码点走的。
'A'自动变成65,这可不是字符拼接那么简单。 - 浮点字面量默认就是 double,整数字面量默认是 int。当目标类型更宽(比如 long、double)时,赋值就会自动发生,完全没问题。
强制转换:可控,但得防着精度与溢出
用 (目标类型) 这个显式的指令,可以让大范围类型往小范围或不兼容的类型强转,但风险就在眼前:
- 浮点数转成整数,直接截断小数部分,
(int)9.99得到9,而不是四舍五入。 - 整数范围缩小时可能溢出,比如
int x = 300; byte y = (byte)x;结果是44(因为 300 对 256 取模)。 - boolean 不能强转,没有继承关系的类之间也不能强制转型。
- 向下转型(如 Object → String)之前,最好用
instanceof检查一下,否则 ClassCastException 随时可能找上门。
字符串与数值互转:已经跳出基本类型范畴
String 不是基本类型,它和数值之间的转换需要调用专门的方法,整个过程完全由你手动控制:
- 数值 → 字符串:推荐用
String.valueOf(x),它对所有基本类型和 null 都很友好。包装类的toString()也行,但传入 null 就会触发空指针。 - 字符串 → 数值:用对应包装类的
parseXxx()方法,比如Integer.parseInt("123")。如果字符串格式不对,就会抛出 NumberFormatException。 - 空或空白字符串转数值之前,务必判空。
StringUtils.isBlank(str)是常用的防护手段。
包装类与基本类型:装箱拆箱简化了,但坑也多了
从 Java 5 开始,自动装箱/拆箱让 Integer 可以用得像 int 一样方便,但一定要注意下面这些点:
- 赋值时自动发生:
Integer i = 100;是装箱,int j = i;是拆箱。 - 只有 -128 到 127 之间的 Integer 值会被缓存。超出这个范围,即使两个对象数值相同,用 == 比较也会返回 false。
- 拆箱时遇到 null 会直接触发 NullPointerException,比如
Integer x = null; int y = x;。 - 在循环中频繁装箱(比如
for(Integer i=0; i<...; i++)),可能引发性能问题甚至内存问题。
