Java:如何使用 clone() 以及强制转换检查呢?

java: how to use clone() and what about the cast check

提问人:Albert 提问时间:10/15/2010 最后编辑:Albert 更新时间:10/15/2010 访问量:8416

问:

此代码:

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()

Java 克隆 编译器-警告

评论


答:

0赞 dty 10/15/2010 #1

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

虽然没有直接相关(因为你不是在写方法),但 Java 泛型 FAQ 中的这篇文章很好读(就像整个 FAQ 一样!clone()

13赞 Péter Török 10/15/2010 #2

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

如果出于某种紧迫的原因,您必须使用但可以更改其实现,请考虑声明返回而不是 - 自 Java5 以来,协变返回类型是合法的。clone()Stack<T>.clone()Stack<T>Object

更新:如果有问题,请考虑其 JavadocStackjava.util.Stack

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

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

评论

0赞 Albert 10/15/2010
Stack<T>就在这里。所以我不能真正改变那里的任何声明。java.util.Stack<T>
0赞 Péter Török 10/15/2010
@Albert,您仍然可以切换到其他集合 - 请参阅我的更新。
2赞 Bozho 10/15/2010 #3

这里没有办法避免演员阵容。 returns ,如果是,则不使用协变返回类型。clone()Objectjava.util.Stack

如果不是,那就不要实现 - 真的很难做到正确。改为制作一个复制构造函数。java.util.Stackclone()

评论

0赞 Péter Török 10/15/2010
您可以(并且建议)将协变返回类型与 - Effective Java 2nd Ed. 第 11 项显示了显式示例。clone()
0赞 Bozho 10/15/2010
是的,但 java.util.Stack 没有。这就是我的观点。我会澄清的
0赞 Albert 10/15/2010
否,没有复制构造函数。否则我会使用它。java.util.Stack
0赞 Grodriguez 10/15/2010 #4

是的,每次使用 时,都需要显式禁止显示警告。clone()

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

顺便说一句,在您的代码中,当使用构造函数时,不需要第一次初始化:RawStringIterator(RawStringIterator i)stateStack

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

您可能需要将其删除。