我应该什么时候使用类的Java5方法强制转换?

我应该什么时候使用类的Java5方法强制转换?,java,java-5,Java,Java 5,通过查看一些代码,我发现了以下代码 trTuDocPackTypdBd.update(TrTuDocPackTypeDto.class.cast(packDto)); 我想知道这种铸造方式是否比 trTuDocPackTypdBd.update((TrTuDocPackTypeDto)packDto); 我问过负责的开发人员,他说他使用它是因为它是新的(这对我来说似乎不是一个特别好的理由),但我很好奇什么时候我想使用这种方法。这两种说法都是相同的。挑一个你觉得更可读的。第二种方法在我的经验中

通过查看一些代码,我发现了以下代码

trTuDocPackTypdBd.update(TrTuDocPackTypeDto.class.cast(packDto));
我想知道这种铸造方式是否比

trTuDocPackTypdBd.update((TrTuDocPackTypeDto)packDto);

我问过负责的开发人员,他说他使用它是因为它是新的(这对我来说似乎不是一个特别好的理由),但我很好奇什么时候我想使用这种方法。

这两种说法都是相同的。挑一个你觉得更可读的。第二种方法在我的经验中更为常见,我更喜欢这种方法


当我处理反射时,我倾向于使用cast方法,在这种情况下它读起来更好。其他时候,我发现自己都在使用第二种强制转换方法。

执行此操作的主要情况(IME)是当您需要在泛型类/方法中安全地强制转换时。由于类型擦除,您无法强制转换到
t
,但如果您已获得
类,则这些语句不完全相同。cast方法是一个普通的方法调用(
invokevirtual
JVM指令),而另一个是一个语言构造(
checkcast
指令)。在上面显示的情况下,应使用第二种形式:
(TrTuDocPackTypeDto)packDto

当您有某个变量类型的类实例时,
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;
}
公共集查找(类clz,筛选条件){
List raw=session.find(clz,criteria);/*一个遗留的非通用API*/
Set safe=new HashSet();
用于(对象o:原始)
安全添加(clz.cast(o));
安全返回;
}
这为您提供了一种安全的方法来避免将原始类型强制转换为泛型类型的错误选择:

/* DO NOT DO THIS! */
List raw = new ArrayList();
...
return (List<Widget>) raw;
/*不要这样做*/
List raw=new ArrayList();
...
返回(列表)原始数据;

编译器将警告您,
Unchecked从一个列表转换到另一个列表
,这意味着在省略号中,可能有人在原始列表中添加了一个
Gadget
,当调用方迭代返回的(假定的)列表时,这将最终导致
ClassCastException
Widget
实例。

我找不到cast方法可行而cast语法不可行的示例。 但是,看看代码,如果无法进行强制转换,cast方法会抛出一个没有附加类型信息的ClassCastException,而强制转换语法会给您一些提示(如“无法将Snoopy强制转换为Tyranosorusrex”) :

/**
*将对象强制转换为所表示的类或接口
*通过这个类对象。
*
*@param obj要投射的对象
*@施放后返回对象,如果obj为空则返回空
*
*@如果对象不存在,则抛出ClassCastException
*null,并且不可分配给类型T。
*
*@自1.5
*/
公共T型铸造(对象obj){
if(obj!=null&!isInstance(obj))
抛出新的ClassCastException();
返回(T)obj;
}
第一种形式

trTuDocPackTypdBd.update(TrTuDocPackTypeDto.class.cast(packDto));
您可以这样做:

public void dynamicCast( Class clazz, Object o ) { 
     this.x = clazz.cast( o );
}
第二次你不能。铸造类应硬编码


为什么首先要使用变量强制转换?这是另一个问题首先想到的是,您不知道(在编译时)将被强制转换到的类

快速扫描语言引用时,
class.cast()
似乎会绕过编译器通常显示的“不安全转换”警告。正如埃里克森所说,使用语言结构直到你不能为止你能解释一下在第二种情况下你应该怎么做吗?我昨天刚遇到这个编译器警告,但忽略了它,因为我很懒。你是在建议类似List.cast(raw)的东西吗?@unclaw——为了避免第二种情况,你需要使用我在上面的“find”方法中提供的东西。也就是说,您需要迭代
列表
,并测试每个元素是否真的是一个
小部件
。然后,可以忽略从“(List)raw”中得到的警告。如果您还不知道要将其转换到哪个类(即反射等),则Class.cast()非常有用。通常,您首先要检查Class.isInstance(对象)以确保不会获得CCE。另请参阅
public void dynamicCast( Class clazz, Object o ) { 
     this.x = clazz.cast( o );
}