Java中这两种强制转换方法的区别是什么?
Java中这两种强制转换方法的区别是什么
(CastingClass) objectToCast;
CastingClass.class.cast(objectToCast);
Class#cast(Object)
的来源如下:
public T cast(Object obj) {
if (obj != null && !isInstance(obj))
throw new ClassCastException();
return (T) obj;
}
所以,cast
基本上是cast操作的通用包装器,但我仍然不明白为什么需要一个方法来实现它
# 1 楼答案
第一个是普通演员。它要求转换到的类型在编译时已知。它在编译时验证强制转换是否可以正确,并在运行时检查(如果要强制转换到的类型不是泛型)强制转换是否正确
第二个使用反射api。它要求在运行时已知要强制转换到的类。它不会在编译时验证任何内容,但总是在运行时检查强制转换是否正确
类型参数仅在编译类型时已知,因此不能对类型参数使用第二种方法(表达式
T.class
不编译)动态加载的类(例如带有Class.forName(String))仅在运行时已知,因此不能使用第一种方法
编辑:但是,正如Pavel指出的,强制转换到动态加载的类是没有意义的。我同意
Class.cast(Object)
唯一真正有用的地方是强制转换为一个类型参数,而您恰好有一个类对象可用如果要转换到的类型不包含类型参数,那么第一种方法更好,因为额外的编译时检查可以捕获bug,在运行时不会丢失类型安全性,并且可以获得更短的启动语法
# 2 楼答案
因为当
T
是泛型类型参数时(由于类型擦除),不能只写(T)objectToCast
。Java编译器将允许您这样做,但是T
在那里将被视为Object
,因此强制转换将始终成功,即使您正在强制转换的对象实际上不是T
的实例# 3 楼答案
Here您可以找到一个使用
Class#cast()
的示例。它可能会提供新的见解# 4 楼答案
对于静态链接的类,只能使用第一种形式
在许多情况下,这还不够——例如,您可能已经使用反射获得了类实例,或者它被作为参数传递给了您的方法;因此,第二种形式
# 5 楼答案
在第一个示例中,您需要对铸造类进行硬编码
在第二种情况下,铸造类可能是一个参数: