java:如何使用clone()以及如何使用cast检查

这段代码:

class RawStringIterator { java.util.Stack stateStack = new java.util.Stack(); RawStringIterator(RawStringIterator i) { stateStack = (java.util.Stack) i.stateStack.clone(); } /* ... */ } 

给了我这个警告:

 Type safety: Unchecked cast from Object to Stack 

我想我可以忽略这里的警告。 但我想知道如何使用clone()一般? 每次使用clone()时,我是否总是必须使用@SuppressWarnings("unchecked") clone() ? 或者我应该总是进行完全冗余的额外检查吗?

如果你有选择,最好不要实现/使用clone() ,因为它是一个破坏的API 。 只需实现/使用复制构造函数即可。

如果由于某些紧迫的原因你必须使用clone()但是可以改变它的实现,考虑声明Stack.clone()返回Stack而不是Object – 协变返回类型从Java5起是合法的。

更新:如果有问题的Stackjava.util.Stack ,请考虑它的Javadoc :

Deque接口及其实现提供了更完整和一致的LIFO堆栈操作集,应优先使用此类。

例如, ArrayDeque提供了一个复制构造函数 。

这里没有办法避免演员。 clone()返回Object ,如果它是java.util.Stack ,则它不使用共变量返回类型。

如果这不是java.util.Stack ,那么不要实现clone() – 它很难做到正确。 改为创建一个复制构造函数。

你别无选择,只能忽略它。

虽然没有直接相关(因为你没有编写clone()方法),但Java Generics FAQ中的这个条目可以很好地阅读(整个常见问题解答!)

是的,每次使用clone()时都需要明确禁止警告。

这是您可能更喜欢使用复制构造函数而不是clone()的原因之一clone()如果可用)。

顺便提一下,在你的代码中,当使用RawStringIterator(RawStringIterator i)构造函数时, stateStack的第一次初始化是不必要的:

 class RawStringIterator { Stack stateStack = new Stack(); RawStringIterator(RawStringIterator i) { stateStack = (Stack) i.stateStack.clone(); } /* ... */ } 

您可能想删除它。