此代码:
class RawStringIterator {
java.util.Stack<State> stateStack = new java.util.Stack<State>();
RawStringIterator(RawStringIterator i) {
stateStack = (java.util.Stack<State>) i.stateStack.clone();
}
/* ... */
}
给了我这个警告:
Type safety: Unchecked cast from Object to Stack<Utils.OperatorTree.RawStringIterator.State>
我想我可以忽略这里的警告。但我想知道如何一般使用clone()
?每次使用@SuppressWarnings("unchecked")
时,我是否总是必须使用clone()
?或者我应该总是进行完全冗余的额外检查吗?
答案 0 :(得分:12)
如果您有选择,最好不要实施/使用clone()
,因为it is a broken API。只需实现/使用复制构造函数。
如果由于某些紧迫的原因您必须使用clone()
但可以更改其实施,请考虑声明Stack<T>.clone()
返回Stack<T>
而不是Object
- 协变返回类型是合法的Java5中。
更新:如果相关的Stack
为java.util.Stack
,请考虑its Javadoc:
Deque
接口及其实现提供了一套更完整,更一致的LIFO堆栈操作,应优先使用该类。
答案 1 :(得分:2)
这里没有办法避免演员。 clone()
会返回Object
,如果是java.util.Stack
,则不会使用共变量返回类型。
如果这不是java.util.Stack
,那么就不要实施clone()
- 要做到这一点真的很难。改为创建一个复制构造函数。
答案 2 :(得分:0)
你别无选择,只能忽略它。
虽然没有直接相关(因为您没有编写clone()
方法),但Java Generics FAQ中的此条目可以很好地阅读(整个常见问题解答!)
答案 3 :(得分:0)
是的,每次使用clone()
时都需要明确禁止警告。
这是您可能更喜欢使用复制构造函数而不是clone()
的原因之一(如果可用)。
顺便提一句,在代码中,当使用RawStringIterator(RawStringIterator i)
构造函数时,stateStack
的第一次初始化是不必要的:
class RawStringIterator {
Stack<State> stateStack = new Stack<State>();
RawStringIterator(RawStringIterator i) {
stateStack = (Stack<State>) i.stateStack.clone();
}
/* ... */
}
您可能想删除它。