Java中这两种强制转换方法的区别是什么?
Java中这两种强制转换方法的区别是什么Java中这两种强制转换方法的区别是什么?,java,casting,Java,Casting,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基本上是
(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操作的通用包装器,但我仍然不明白为什么需要一个方法。因为当t
是一个通用类型参数时(由于类型擦除),您不能只编写(t)objectToCast
。Java编译器将允许您这样做,但是T
在那里将被视为Object
,因此强制转换将始终成功,即使您正在强制转换的对象实际上不是T
的实例 对于静态链接的类,只能使用第一种形式
在许多情况下,这还不够——例如,您可能已经使用反射获得了类实例,或者它被作为参数传递给了您的方法;因此出现了第二种形式。第一种是普通铸造。它要求转换到的类型在编译时已知。它在编译时验证强制转换是否正确,并在运行时检查(如果要强制转换到的类型不是泛型)强制转换是否正确 第二个使用反射api。它要求在运行时已知要强制转换到的类。它不会在编译时验证任何内容,但总是在运行时检查强制转换是否正确 类型参数仅在编译类型时已知,因此不能对类型参数使用第二种方法(表达式
T.class
不编译)
动态加载的类(例如带有Class.forName(String))仅在运行时已知,因此不能使用第一种方法
编辑:但是,正如Pavel指出的,强制转换到动态加载的类是没有意义的。我同意,Class.cast(Object)
唯一真正有用的功能是对一个类型参数进行强制转换,而您恰好有一个Class对象可用
如果要强制转换到的类型不包含类型参数,则第一种方法更好,因为额外的编译时检查可以捕获错误,在运行时不会丢失类型安全性,并且可以获得较短的启动语法。您可以找到一个使用
Class#cast()
的使用示例。它可能会提供新的见解。在第一篇文章中,您将硬编码铸造类
( ClassToCast ) objectToCast;
在第二种情况下,铸造类可能是一个参数:
Class toCast = getClassToCast();
toCast.cast( objectToCast );
好的,我刚刚意识到可以使用
cast
来强制转换到基本类型的包装器。例如,整数i=int.class.cast(“1234”)
@simmbot:你可以写这个,但它不会做你最可能认为它会做的事情。试试看。这会抛出一个ClassCastException,因为String不是Integer类型。在这种情况下,您需要Integer.valueOf(“1234”)
。嗨,Pavel,您介意再解释一下吗cast
似乎就是这样做的:return(T)obj代码>你肯定能写出来。它只是发出一个编译器警告。@meriton:说得好,编辑好了。我想说的是,cast仍然不会做它真正应该做的事情。@simmbot:它会做,但在做之前它也会做一个显式的类型检查(因为cast本身不会这样做)。因此,它与普通的(Type)对象
cast一样是类型安全的-如果对象实际扩展或实现了T
,它将只返回类型为T
的引用,否则它将抛出。@PavelMinaev但“静态”cast(Type)对象
。如果对象
不是类型
的实例,那么将抛出类castException,对吗?那么这两种方式有什么区别呢?对。在第一种形式中,您正在源代码中“烘焙”强制转换。不重新编译就无法更改它。第二种形式允许您尝试对任意类进行强制转换。但是,对于动态加载的类,为什么需要强制转换呢?强制转换通常是强制表达式具有某种类型,但在动态加载类的情况下,您事先不知道该类型。毕竟,如果您有一个动态加载的类,您不知道对class.cast()
的调用中的t
是什么,所以您只需要使用原始版本,然后返回类型将是Object
——这不是什么强制转换。它会检查类型,但肯定Class.isInstance()
是一种更好的方法。总而言之,在我看来,这只是针对泛型的。