显式类型转换必须用于窄化转换,如double→int、long→short等;语法为(目标类型)表达式,注意括号位置;数值转换会截断而非四舍五入,可能溢出;引用类型转换需满足继承关系且运行时类型匹配,否则抛ClassCastException。
在Java中,显式类型转换(也叫强制类型转换)是指程序员主动用括号指定目标类型,将一个变量或表达式从一种类型转为另一种类型。它主要用于窄化转换(narrowing conversion),比如把 double 转成 int、long 转成 short,这类转换可能丢失精度或溢出,编译器不自动允许,必须显式声明。
当目标类型比源类型“更小”(即取值范围更窄、占用内存更少)时,Java要求显式转换:
double → float、int、short、byte
long → int、short、byte
int → short、byte、char
char → byte、short(注意:char 是无符号的0–65535,转有符号类型可能产生负数)显式转换格式为:(目标类型) 表达式。括号必须紧贴目标类型,不能有空格隔开(如 (int) x 正确,( int ) x 虽可编译但不规范)。
转换作用于整个表达式,优先级高于算术运算符。例如:
int a = (int) 3.14 + 2; → 先转 3.14 为 3,再加 2 得 5
int b = (int) (3.14 + 2); → 先算和 5.14,再转为 5
务必注意括号位置,否则语义不同。
Java不做运行时范围检查,显式转换只做位截取(bit truncation)或低字节保留,可能导致意外结果:
double d = 128.9; int i = (int) d; → 结果是 128(直接丢弃小数部分,不四舍五入)int x = 300; byte b = (byte) x; → 300 的二进制低8位是 00101100(即 44),所以 b == 44
int y = -1; byte c = (byte) y; → -1 的补码全为1,取低8位仍是 11111111,即 -1
这种静默截断不会抛异常,容易埋下bug,建议配合逻辑判断或使用 Math.toIntExact() 等安全方法(会抛 ArithmeticException)。
显式转换也适用于引用类型,但仅限有继承/实现关系的对象,且必须满足“实际运行时类型能被安全视为目标类型”,否则抛 ClassCastException:
Object obj = new String("hello"); String s = (String) obj; → 合法Object obj = new Integer(123); String s = (String) obj; → 编译通过,运行时报错instanceof 检查:if (obj instanceof String) { s = (String) obj; }
泛型类型擦除后无法做强制转换(如 (List 是无效的,只会触发 unchecked 警告)。
基本上就这些。显式转换不是难事,但容易忽略精度损失和运行时风险。写的时候多想一步“值是否在目标范围内”“对象到底是不是那个类型”,能避开大多数坑。