从返回的界面转换?总是安全吗?

时间:2012-11-06 00:31:37

标签: java casting type-safety

说我有这个功能:

public Set<String> giveUp()
{
    Set<String> alreadyGuessed = guessed;
    guessed = new LinkedSet<String>();

    //fill Guessed with possible words
    anag(currentWord, "");

    //Remove ones already guessed
    Iterator<String> alGuessIterator = alreadyGuessed.iterator();
    while (!alGuessIterator.done())
    {
        guessed.remove(alGuessIterator.get());
        alGuessIterator.advance();
    }

    return guessed;
}

当我调用此函数并尝试使用如下行来存储它时:

LinkedSet<String> notGuessed = (LinkedSet<String>)wordGame.giveUp();

无论上述功能的内部实现如何,这总是安全吗?换句话说,不能猜到是一个ArraySet,它仍然保持一个非常安全的演员?或者我误解了返回的界面的意义,我只是应该有“Set notGuessed”以防止需要进行投射?

我的老师在课堂上的问题上没用,如果我做任何不安全的演员,我也会立即给我一个。

5 个答案:

答案 0 :(得分:2)

这不安全,因为您无法确定基础类型。如果您只需要访问Set接口定义的方法,那么您应该使用:

Set<String> set = wordGame.giveUp();

如果这恰好是LinkedSet您的代码将“正常”,但如果不是,您将获得ClassCastException。如果您出于任何原因需要它LinkedSet,那么giveUp()方法应该明确返回LinkedSet

答案 1 :(得分:0)

不,你的演员表会以ClasscastException失败,除非返回类型与你所投射的类型完全相同。

阅读此文章以了解why program to an interface

答案 2 :(得分:0)

不,您将返回Set并转换为LinkedSet。

如果你改变了

Set<String> alreadyGuessed = guessed;
guessed = new LinkedSet<String>();

Set<String> alreadyGuessed = guessed;
guessed = new HashSet<String>();

你将有一个classcastexception。

链接集是一个集合,但集合不一定是链接集。除非您在代码中使用特定于Linkedset的方法,否则只需删除强制转换。

答案 3 :(得分:0)

如果不将全局字段用于仅在本地使用的内容,则会更好。在这种情况下,您应该在本地声明guessed,然后让anag返回一些内容。

将事物保持在正确的范围内有时很烦人,但可以防止你在这里遇到的确切混乱。

就您询问的实际问题而言,让方法返回LinkedSet,那么您不必担心投射。

答案 4 :(得分:0)

返回接口引用类型的整个想法是所有用户都应该对它提供的方法感到满意,而不必担心底层实现。如果你必须施展,你做错了。