Exception 如果调用公共函数已经进行了检查,则私有函数中的断言是否冗余?

Exception 如果调用公共函数已经进行了检查,则私有函数中的断言是否冗余?,exception,nullpointerexception,Exception,Nullpointerexception,有效的java声明了在私有方法中断言的良好实践 “对于未报告的方法,作为包作者,您可以控制调用该方法的环境,因此您可以并且应该确保只传入有效的参数值。因此,非公共方法通常应使用断言检查其参数,如下所示: 例如: // Private helper function for a recursive sort private static void sort(long a[]) { assert a != null; // Do the computation; } 我的问题是,即

有效的java声明了在私有方法中断言的良好实践

“对于未报告的方法,作为包作者,您可以控制调用该方法的环境,因此您可以并且应该确保只传入有效的参数值。因此,非公共方法通常应使用断言检查其参数,如下所示:

例如:

// Private helper function for a recursive sort
private static void sort(long a[]) {
    assert a != null;
    // Do the computation;
}
我的问题是,即使调用排序的公共函数具有空指针检查,是否也需要断言

例如:

public void computeTwoNumbersThatSumToInputValue(int a[], int x) {
    if (a == null) {
      throw new Nullptrexception();
    }
    sort(a);
    // code to do the required.
}
换句话说,在这种情况下,私有函数中的断言是“冗余”还是强制的


谢谢,

断言将使helper函数sort使用起来更加健壮。 在将参数传递给任何方法之前检查参数是一种很好的方法,可以更好地控制在运行时意外发生的异常

我的建议是在代码中同时使用这两种方法,因为不能保证所有的排序调用方都会进行这样的检查。如果助手方法中的断言在算法上是高阶的,或者看起来是冗余的,那么这可以被禁用(特别是用于生产)通过使用命令行中的-disableassertions或-da。

如果您确信在所有调用代码中都有断言,那么这是多余的。在某些情况下,这是非常明显的,在其他情况下可能不是这样。如果您从类中的20个位置调用
sort
,您确定在每种情况下都检查了它吗

这是一个品味和平衡的问题,没有“一刀切”的答案。平衡是在代码清晰性(双向!)、性能(在极端情况下)和安全性方面。这取决于确切的上下文,我个人甚至不想保证我完全一致。(换句话说,”编码时的咖啡因水平“可能也会产生影响。)


请注意,您的
assert
仅在断言被打开时才会执行-我个人更喜欢在运行代码时一致地验证参数。我通常使用中的类使前提条件不引人注目。

您可以这样做。我将引用文档中的内容

断言是JavaTM编程语言中的一条语句 使您能够测试有关程序的假设。例如, 如果编写计算粒子速度的方法,则 可能会断言计算的速度小于 光

我个人不使用断言,但从我收集的oracle文档来看,它使您能够测试您对期望做什么的假设。Try/catch块更适合优雅地失败,因为失败不可避免(如网络、计算机问题)。基本上,在一个完美的世界中,您的代码始终会成功运行,因为它在代码方面没有任何问题。但这不是一个完美的世界。还要注意:

经验表明,在编程时编写断言是其中之一 最快和最有效的方法来检测和纠正错误 断言还有一个好处,它可以用来记录 您的程序,增强了可维护性

我会说使用作为首选项。为了回答您的问题,我主要使用它来测试代码,正如文档所说,同时测试您对代码的假设。正如第二段所提到的,它还有告诉其他开发人员(或未来的您)的额外好处作为个人偏好,我将控制流留给try/catch块,因为这就是它们的设计目的


*但是请记住,断言可以关闭。

旁注:与
inta[]相比,更喜欢
inta[]
;后一种语法仅因传统原因而受支持,而前一种语法作为样式更受欢迎。您将灰色部分作为代码块编写的原因是什么?这会使它们更难阅读。假设它们是引号,链接到您引用的页面也会有所帮助。Better@JonSkeet?谢谢您指出这一点。我很抱歉老实说,我不知道有一个引号选项,我只是忘了添加源代码。@Andy:更好,虽然它并没有真正回答IMO的问题。你的答案只是关于断言是否是一个好主意,而问题是关于编写已经在调用中测试过的私有方法断言代码。