假设我们有一个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();
}
现在,查找度数的调用是检查顶点绑定条件两次。
这意味着我们正在进行冗余检查。在这种情况下,异常处理的最佳做法是什么?
答案 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。