Java: Design by Contract 注释

Java: Design by Contract annotations

我最近开始阅读契约式设计方法,但我不理解它的某些方面。当在 javadoc 样式注释中使用 @pre 等时,这些标签除了作为文档之外还有什么用途?编译器是否在执行前使用这些来检查参数,或者这些只是指示方法中应该进行哪种检查的指标?例如如果我有 getAge 方法;

/**
* @pre age >= 0 #CustomAgeException
*/
public int getAge() throws CustomAgeException{
    return age;
}

这会导致在 运行 方法之前在运行时进行检查吗?编译器是否检查这个,或者这只是向开发人员声明在调用此方法之前年龄必须等于或大于 0,以及应该在 getAge 中执行检查吗?

运行时无法访问 JavaDoc。 .class 文件不包含它们。 (参考见此处 Whosebug question)因此,任何检查 javadoc 的代码都是不可能的。

注释只是为了制作漂亮的 javadoc,或者在 类 中对这些注释保持相同的模式。 您必须自己实施检查,或者使用某种框架来实际执行检查。 (也许在 method/parameter 水平上有真正的注释)

此致

Java 不直接支持按合同设计。正如 Robin Jonsson 所说,JavaDoc 在运行时无法访问。

但是,您可以使用不同的工具,例如可以访问注释的 JMSAssert。更多详情:http://www.mmsindia.com/JMSAssert.html

规范(例如按合同设计的注释)记录了代码的行为方式。这作为文档很有用,这样您就可以找到代码中的错误,并且代码的客户可以正确使用它。

最好有经过机器检查的文档,这样您就可以保证您的代码没有错误并且客户可以正确使用它。 运行 时间断言可以帮助解决这个问题,但它们不能保证:它们可能会在 运行 时间失败。

正如您在问题中所问,编译器最好在执行前检查规范。 (不幸的是,其他答案忽略了你问题的这一部分,而是专注于 运行 时间检查。)有多种框架可以对规范进行编译时检查。由于问题通常无法确定,因此所有框架都有局限性,但您可能会发现它们仍然有用。一个不错的选择是 Checker Framework,它允许您定义类型注释,例如 @NonNegative,将它们写在您的代码中,编译器会验证您的代码是否与注释一致。