查看一些代码,我遇到了以下代码
trTuDocPackTypdBd.update(TrTuDocPackTypeDto.class.cast(packDto));
我想知道这种方式是否有任何优势
trTuDocPackTypdBd.update((TrTuDocPackTypeDto)packDto);
我已经问开发人员负责了,他说他使用它是因为它是新的(这对我来说似乎不是特别好的理由),但是当我想要使用这种方法时,我很感兴趣。 / p>
答案 0 :(得分:20)
这些陈述并不完全相同。 cast方法是普通的方法调用(invokevirtual
JVM指令),而另一种是语言构造(checkcast
指令)。如果您在上面显示,则应使用第二种形式:(TrTuDocPackTypeDto) packDto
当您为某些变量类型设置Class实例时,cast
方法用于带泛型的反射编程。您可以像这样使用它:
public <T> Set<T> find(Class<T> clz, Filter criteria) {
List<?> raw = session.find(clz, criteria); /* A legacy, un-generic API. */
Set<T> safe = new HashSet<T>();
for (Object o : raw)
safe.add(clz.cast(o));
return safe;
}
这为您提供了一种安全的方法来避免将原始类型简单地转换为泛型类型的错误替代方法:
/* DO NOT DO THIS! */
List raw = new ArrayList();
...
return (List<Widget>) raw;
编译器会警告你,Unchecked cast from List to List<Widget>
,这意味着在省略号中,有人可能在原始列表中添加了Gadget
,当调用者迭代时最终会导致ClassCastException
返回(假设的)Widget
个实例的返回列表。
答案 1 :(得分:4)
执行此操作(IME)的主要情况是您需要安全地转换为泛型类/方法。由于类型擦除,您无法转换为T
,但如果您已经提供了Class<? extends T>
参数,则可以使用该参数进行转换,结果将可分配给{{1}类型的变量1}}。
答案 2 :(得分:0)
我找不到一个示例,其中可以使用强制转换方法,而不能使用强制转换语法。 但是,查看代码时,似乎在无法进行强制转换的情况下,cast方法抛出一个没有附加类型信息的ClassCastException,而强制转换语法会给你一些提示(如“,”无法将Snoopy强制转换为TyrannosorusRex “) :
/**
* Casts an object to the class or interface represented
* by this <tt>Class</tt> object.
*
* @param obj the object to be cast
* @return the object after casting, or null if obj is null
*
* @throws ClassCastException if the object is not
* null and is not assignable to the type T.
*
* @since 1.5
*/
public T cast(Object obj) {
if (obj != null && !isInstance(obj))
throw new ClassCastException();
return (T) obj;
}
答案 3 :(得分:0)
使用第一个表格
trTuDocPackTypdBd.update(TrTuDocPackTypeDto.class.cast(packDto));
你可以这样做:
public void dynamicCast( Class clazz, Object o ) {
this.x = clazz.cast( o );
}
用第二个你不能。铸造类应该是硬编码的。
为什么要在第一时间使用变量?那是另一个问题。 :)首先想到的是,你不知道(在编译时)将被转换为的类。
答案 4 :(得分:-3)
这两个陈述都是相同的。选择你认为更具可读性的那个。第二种方法在我的经验中更常见,而且它是我喜欢的一次。
我倾向于仅在使用反射时使用强制转换方法,并且在这种情况下它看起来更好。所有其他时间我发现自己使用第二种方式。