在包装类的情况下如何处理异常?

时间:2013-08-15 13:00:40

标签: java exception exception-handling

假设我们有一个Graph类和另一个名为GraphWrapper的类。 Graph类有一个名为returnAdjVertices的方法。

public List returnAdjVertices(int vertex) {
    if (vertex < 0 || vertex >= maxVertexCount) {
        throw exception
    }
}

现在我们在GraphWrapper中有一个包装函数,它可以计算顶点的度数

public static int getDegree(Graph graph, int vertex) {
    if (graph == null) throw new NullPointerException();
    if (vertext < 0 || vertex >= graph.maxVertexCount) throw exception // REDUNDANT

    return graph.returnAdjVertices(vertex).size();
}

现在,查找度数的调用是检查顶点绑定条件两次。

这意味着我们正在进行冗余检查。在这种情况下,异常处理的最佳做法是什么?

3 个答案:

答案 0 :(得分:2)

您可以重新抛出异常(如果您没有在包装中捕获它,它将自动完成)

public static int getDegree(Graph graph, int vertex) throws VertexOutOfBoundsException {
    return graph.returnAdjVertices(vertex).size();
}

或者在你的包装器中捕获它并重新转换为另一个

public static int getDegree(Graph graph, int vertex) throws WrapperException {
    int result;
    try {
        result = graph.returnAdjVertices(vertex).size();
    } catch (VertexOutOfBoundsException e) {
        throw new WrapperException();
    }
    return result;
}

甚至抓住它并尝试修复它

public static int getDegree(Graph graph, int vertex) {
    int result;
    try {
        result = graph.returnAdjVertices(vertex).size();
    } catch (VertexOutOfBoundsException e) {
        result = fixGraphAndReturnAdjVertices(graph, vertex);
    }
    return result;
}

你不应该再次检查,因为它很难维持 变体的选择始终是情境性的 当包装器与包装对象处于相同的抽象级别时,第一个变体(自动重新抛出)很好 当包装器和包装对象处于不同的抽象级别时,第二个变体很好,作为一个例子,我可以建议使用HDD的对象的“FileNotFoundException”可以转换为类似于“CannotLoadDataException”的对象,如果它尝试加载某些东西对于来电者来说,究竟出现了什么问题 当您的包装器可以修复东西时,第三个变体很好:) 所以这完全取决于你。希望我的回答有所帮助。

答案 1 :(得分:0)

如您所知,检查是多余的。所以你可以简单地从包装器中删除它。异常将向上移动一堆调用。

我会在两种方法的文档中明确指出,当顶点不在接受的边界之间时会抛出异常。或者至少在包装器方法的文档中明确表示它在内部调用包装方法,因此抛出相同的异常。

答案 2 :(得分:0)

在这个特定的案例中?它是多余的,应该被删除 - 至少如果你要抛出相同的异常,并且代码中没有其他可能的副作用。

一般案例中?它完全依赖 来满足您的需求,代码等。

一个问题是,如果您的显式意图是执行完全相同的检查,则需要监视包装类以确保保护子句未更改,或者将保护逻辑提取到可以调用的单独方法中独立。但这是封装泄漏。

另外,我会抛出IllegalArgumentException一条消息而不是NPE。