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
基本上是强制转换操作的通用包装器,但我仍然不明白为什么你需要一个方法。
您只能将第一个表单用于静态链接的类。
在许多情况下这还不够 – 例如,您可能已经使用reflection获取了类实例,或者它已作为参数传递给您的方法; 因此第二种forms。
因为你不能只写(T)objectToCast
,当T
是generics类型参数时(由于类型擦除)。 Java编译器会让你这样做,但是T
将被视为Object
,所以即使你正在构建的对象不是T
的实例,强制转换也会成功。
这首先是普通演员。 它要求在编译时知道要转换的类型。 它在编译时validation转换是否正确,并检查(如果要转换为的类型不是通用的)转换在运行时是正确的。
第二个使用reflectionapi。 它要求在运行时知道要转换的类。 它在编译时不validation任何内容,但始终在运行时检查强制转换是否正确。
类型参数仅在编译类型中已知,因此您不能将第二种方法用于类型参数(表达式T.class
不编译)。
动态加载的类(例如使用Class.forName(String))仅在运行时已知,因此不能使用第一种方法。
编辑:但是,正如Pavel指出的那样,强制转换为动态加载的类是没有意义的。 我同意Class.cast(Object)
唯一真正有用的是Class.cast(Object)
为恰好有类对象可用的类型参数。
如果要转换为的类型不包含类型参数,则第一种方法更好,因为额外的编译时检查可以捕获错误,在运行时不会丢失类型安全性,并且需要更短的语法来引导。
在第一个中,您必须对铸造类进行硬编码。
( ClassToCast ) objectToCast;
在第二个中,转换类可能是一个参数:
Class toCast = getClassToCast(); toCast.cast( objectToCast );
在这里,您可以找到使用Class#cast()
的用例。 它可能会给出新的见解。