ClassCastException与Generic Collections中的instanceOf

时间:2015-12-08 09:50:21

标签: java generics classcastexception instanceof

我有一个实现Collection<E>的课程。

当我检查我的收藏是否包含一个项目时,界面的方法会给出一个对象的参数,当它必须是<E>

你认为它是正常的&#34;写这段代码:

@Override
public boolean contains(Object o)
{
    E item;
    try
    {
        item=(E) o;
    }
    catch (ClassCastException e)
    {
        return false;
    }
    //check if contains "item"
}

我知道通常使用try,catch检查对象的类型是个糟糕的主意,但在通用集合中,我无法通过instanceOf检查并且我不会&# 39;找到更好的解决方案。

4 个答案:

答案 0 :(得分:2)

来自javadoc它说:

  

抛出:ClassCastException - 如果指定元素的类型与此集合不兼容(可选)

所以编码它是完全可以接受的:

    @Override
    public boolean contains(Object o) {
        T item = (T) o;
        // ...
    }

如果演员表失败,则会抛出ClassCastException

你当然应该隐藏该异常并悄悄地返回false - 这可能会在用户代码中留下许多潜在的错误。

答案 1 :(得分:2)

如果您的集合类具有E作为没有边界的泛型类型参数,则您的检查无效 - 强制转换无法失败,因为强制转换是完全未选中的。如果E无限制,Object将被删除为item=(Object) o;,您的演员阵容将为instanceof,这不会失败。它可能导致其他地方的其他失败,但它不能在这里失败,如果它在其他地方失败,以后你的try-catch不能捕获它。

您无法使用instanceof的事实应该告诉您一些事情 - instanceof无法使用的原因是因为它是运行时检查,需要在运行时检查类,并且你没有在运行时的类。尝试使用强制转换失败也是运行时检查,因此它根本不会改善您的情况。依赖转换为失败仅适用于instanceof工作的相同情况,因此从不对“使用强制转换是有意义的,因为@Override public boolean contains(Object o) { Object item; try { item= o; } catch (ClassCastException e) // does this make sense? { return false; } //check if contains "item" } 不起作用”。< / p>

编写通用代码时,重要的是要考虑类型擦除后代码的样子。当您将通用代码删除为非通用代码时(通过在适当的位置添加强制转换),代码应该相同。如果无法将代码编写为非泛型,则也不能将其写为通用代码。

KMeansModel model = KMeans.train(trainingData.rdd(), numClusters,
                numIterations);

答案 2 :(得分:1)

您可以在此方法中抛出ClassCastException,因此您不能检查类型。阅读Collection接口的javadoc。

答案 3 :(得分:0)

Imho你应该使用参数对象的equals / hashCode方法来检查它是否存在于你的集合中。根本不需要Casting或instanceof。