[英]What is the difference between these two ways of casting in Java?
What is the difference between these two ways of casting in Java? Java中这两种投射方式有什么区别?
(CastingClass) objectToCast;
CastingClass.class.cast(objectToCast);
The source of Class#cast(Object)
is as follows: Class#cast(Object)
的来源如下:
public T cast(Object obj) {
if (obj != null && !isInstance(obj))
throw new ClassCastException();
return (T) obj;
}
So, cast
is basically a generic wrapper of the cast operation, but I still don't understand why you would need a method for it. 因此, cast
基本上是强制转换操作的通用包装器,但我仍然不明白为什么你需要一个方法。
You can only use the first form for statically linked classes. 您只能将第一个表单用于静态链接的类。
In many cases that's not enough - for example, you may have obtained class instance using reflection or it was passed to your method as parameter; 在许多情况下,这还不够 - 例如,您可能已经使用反射获取了类实例,或者它已作为参数传递给您的方法; hence the second form. 因此第二种形式。
Because you cannot just write (T)objectToCast
, when T
is a generic type parameter (due to type erasure). 因为你不能只写(T)objectToCast
,当T
是泛型类型参数时(由于类型擦除)。 Java compiler will let you do that, but T
will be treated as Object
there, so the cast will always succeed, even if the object you're casting isn't really an instance of T
. Java编译器会让你这样做,但是T
将被视为Object
,所以即使你正在构建的对象不是T
的实例,强制转换也会一直成功。
This first is an ordinary cast. 这首先是普通演员。 It requires that the type to cast to is known at compile time. 它要求在编译时知道要转换的类型。 It verifies at compile time that the cast can be correct, and checks (if the type to cast to is not generic) that the cast is correct at runtime. 它验证在编译时,中投可能是正确的,并检查(如果类型强制转换为不通用),中投是在运行时正确的。
The second uses the reflection api. 第二个使用反射api。 It requires that the class to cast to is known at runtime. 它要求在运行时知道要转换的类。 It doesn't verify anything at compile time, but always checks that the cast is correct at runtime. 它在编译时不验证任何内容,但始终在运行时检查强制转换是否正确。
Type parameters are only known at compile type, hence you can not use the second approach for a type parameter (the expression T.class
does not compile). 类型参数仅在编译类型中已知,因此您不能将第二种方法用于类型参数(表达式T.class
不编译)。
Dynamically loaded classes (for instance with Class.forName(String)) are only known at runtime, hence the first approach can not be used. 动态加载的类(例如使用Class.forName(String))仅在运行时已知,因此不能使用第一种方法。
Edit: However, as Pavel points out, it makes no sense to cast to a dynamically loaded class. 编辑:但是,正如Pavel指出的那样,强制转换为动态加载的类是没有意义的。 I agree that the only real usefulness of Class.cast(Object)
is to cast to a type parameter for which you happen to have a class object available. 我同意Class.cast(Object)
唯一真正有用的是Class.cast(Object)
为恰好有类对象可用的类型参数。
If the type to cast to does not contain a type parameter, the first approach is better, as the additional compile time checking can catch bugs, you lose no type safety at runtime, and get a shorter syntax to boot. 如果要转换为的类型不包含类型参数,则第一种方法更好,因为额外的编译时检查可以捕获错误,在运行时不会丢失类型安全性,并且需要更短的语法来引导。
In the first one you have to hardcode the casting class. 在第一个中,您必须对铸造类进行硬编码。
( ClassToCast ) objectToCast;
In the second one the casting class maybe a parameter: 在第二个中,铸造类可能是一个参数:
Class toCast = getClassToCast();
toCast.cast( objectToCast );
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.