Java中的类型转换机制(type casting)允许程序员显式或隐式地将一种类型的值转换为另一种类型。这一特性历史上源于C和C++,但在Java中被限制以增强类型安全性,防止与溢出或数据丢失相关的隐藏错误。
问题在于,在进行引用类型转换时可能会发生ClassCastException,同时在进行基本类型转换时会导致精度丢失,例如从double转换为int。在进行所谓的“下转型”(downcasting)时,如果实例不属于该类,可能会出现逻辑错误。
解决方案在于严格的划分:
基本类型的代码示例:
int i = 100; long l = i; // 隐式转换 (int -> long) double d = l; // 隐式 (long -> double) int i2 = (int) d; // 显式转换 (丢弃小数部分)
引用类型的代码示例:
Object obj = "Hello"; // 上转型,隐式 String s = (String) obj; // 下转型,显式
关键特点:
Java编译器能否防止所有错误的类型转换?
答:不能,编译器只会在编译阶段捕获明显的错误。如果类型结构中转换是可能的(例如,Object -> String),但变量中实际存储的是不兼容类型的对象,错误只会在运行时表现为ClassCastException。
Integer是否继承自Long,可以写Integer i = (Integer) someLong吗?
答:不能,Integer和Long是独立的包装类,之间不能进行下转型。它们都继承自Number,但不互相之间。像(Integer) (Object) 1L;这样的转换会引发ClassCastException。
在显式转换float到int时,会发生四舍五入吗?
答:不会,发生的是丢弃小数部分而不进行四舍五入:
float f = 3.99f; int i = (int) f; // i == 3,而不是4
开发人员接收到Object集合,将每个元素转换为其类型,但没有检查instanceof。项目在处理不正确的数据时稳定地因ClassCastException而崩溃。
优点:
缺点:
所有的下转型操作都在if (obj instanceof TargetType)内部进行,并明确处理错误。对于集合使用泛型。
优点:
缺点: