我试图掌握在Java中使用assert
关键字的方法。据我所知,正确的情况是验证应该永远属实的事情。
我担心我过度使用断言。
以下是一个示例:
private BodyParams() {
assert revokedDoc != null : "revokedDoc must not be null";
assert revokedDoc.getStatus() == DocumentStatus.Revoked : "document is not revoked";
assert !isBlank(revokedDoc.getDocType()) : "docType should not be blank";
assert revokedDoc.getIssuedDate() != null : "doc should have issue date";
assert revokedDoc.getSendingOrg() != null
&& !isBlank(revokedDoc.getSendingOrg().getName())
: "sending ord should exists and name should ne populated";
if (registeredUser) {
assert revokedDoc.getOwner() != null
&& !isBlank(revokedDoc.getOwner().getFirstName())
: "owner should exists and first name should be populated";
this.ownerFirstName = revokedDoc.getOwner().getFirstName();
this.docUrl = Application.PUBLIC_HOSTNAME
+ controllers.routes.DocumentActions.viewDocument(
revokedDoc.getId()
).url();
} else {
this.ownerFirstName = null;
this.docUrl = null;
}
if (revokedDoc.getStatus() == DocumentStatus.Available) {
assert !isBlank(revokedDoc.getFriendlyName())
: "friendly name should not be blank for picked-up docs";
this.friendlyName = revokedDoc.getFriendlyName();
} else {
this.friendlyName = null;
}
this.docType = revokedDoc.getDocType();
this.issueDate = revokedDoc.getIssuedDate();
this.issuerName = revokedDoc.getSendingOrg().getName();
}
在此示例中,假设revokedDoc字段来自数据库,并在插入时执行了正确的验证。这些断言测试了这个假设。这有点过头了吗?
编辑我应该提到这只适用于开发代码。生产中不会启用断言。我使用断言来确保来自生产中受信任来源的已知良好数据的数据在开发中表现自己
答案 0 :(得分:3)
Assert
非常有用,在库或模块中应该始终为true 。它旨在验证代码中的不变量(控制流,内部等),并且使用它来强制正确使用代码是一个坏主意(你有例外)。
因此,您的公共接口永远不应该基于断言:当您有一个公共方法并且想要检查输入参数时,通常最好抛出IllegalArgumentException
。
Here是一些关于断言的好文档。
在您的示例中,我认为您应该使用异常而不是断言。对来自数据库的数据执行一些有效性检查并不是一个坏主意(即使它已经在输入上验证),但是在生产代码中可能会禁用断言,您必须考虑如何处理这种格式错误的内容。
答案 1 :(得分:3)
看起来不对劲。为简化起见,可能会出现两大类问题,需要检查变量的有效性:
IllegalArgumentException
或NullPointerException
或其他任何内容。示例:客户端代码已传入null参数,并且您无法控制该代码在您的情况下,创建revokeDoc
对象的方法应该确保它在创建后处于有效状态,否则采取适当的操作,例如抛出异常并回滚任何更改。这样你的BodyParams
方法可以只使用该对象而没有所有那些在错误的时间使代码混乱的断言:如果revokeDoc
不一致,那么对它做一些事情可能已经太晚了早先检测到。
答案 2 :(得分:2)
这可能是一个固执己见的问题。但是,我会选择以下事项来决定:
答案 3 :(得分:1)
您需要考虑两种情况:开发代码和生产代码。
由于Java的assert
语句默认是禁用的(并且通过检查通过将-ea
传递给VM而启用的全局静态标志来增加很少的开销),我不会考虑这种开销,因为它可以帮助您在开发阶段早期检测到问题(假设您已在开发环境中启用了断言)。
另一方面,你说" ...插入时进行了正确的验证......" - 那么,你怎么知道数据库中的值没有同时改变?如果安全对您的系统很重要(我只是假设它),一个基本模式是您不能相信从外部获得的任何东西。意味着,验证您从数据库中读取的值 - 但是,在这种情况下,assert
不是正确的工具。使用正常的验证代码和例外。
答案 4 :(得分:0)
根据OO metology的最佳做法是检查你收到的params。并为其他人创建常客检查。在你的情况下你应该得到这样的东西:
private BodyParams(revokedDoc)
[...]
asserts of the params
if(isBlank(revokedDoc.....)
所有资产看起来都很好,并且是确保方法具备所有内容的方法。但他们应该做出错误的帮助,而不是让你的程序运作。