Java 我应该使用先决条件检查来检查中间结果吗?
Guava提供了帮助函数来检查前提条件,但我找不到帮助函数来检查中间结果Java 我应该使用先决条件检查来检查中间结果吗?,java,guava,Java,Guava,Guava提供了帮助函数来检查前提条件,但我找不到帮助函数来检查中间结果 private void foo(String param) { checkNotNull(param, "Required parameter is not set"); int x = get(param); if (x == -1) { throw new RuntimeException("This should never have happened and indica
private void foo(String param)
{
checkNotNull(param, "Required parameter is not set");
int x = get(param);
if (x == -1) {
throw new RuntimeException("This should never have happened and indicates a bug.");
}
}
- 我是否应该将
部分包装在我自己的助手中李>if(…){…}
- 或者我应该使用番石榴的
checkState
- 或者我应该查看由于
而导致的param
失败,并使用get()
checkArgument
- 我应该在这些情况下使用资产吗
- 还是我遗漏了什么李>
get
方法只是将字符串转换为int,那么它应该在那里进行验证,最好抛出一个illegalArgumentException或一些类似的RuntimeException。通过以上内容,您还可以在方法中混合抽象层次。例如,您的checkNotNull
抽象掉了对param
的null检查,但是对param
的检查作为一个int被拆分为get
方法和foo
方法。为什么不使用一个CheckPremission类型方法?例如
private void paramShouldBeNonNullInt(String value) {
if (value == null) throw new IllegalArgumentException("value was null");
try {
Integer.parseInt(value)
} catch (NumberFormatException e) {
throw new IllegalArgumentException("value was not an integer");
}
}
这是一个介于偏好和惯例之间的问题 通常,人们会使用断言来表示编程错误;也就是说,“如果我正确地完成了我的工作,那么非null的
参数
永远不会导致来自get
的-1,而不管用户输入或其他外力如何。”我几乎将它们视为可选择在运行时验证的注释
另一方面,如果get
在某些情况下可能返回-1,但该输入无效,那么我通常会抛出IllegalArgumentException
,而checkArgument
是一种非常合理的方法。它的一个缺点是,当你后来发现它时,它可能来自几乎任何地方。考虑:
try {
baz();
bar();
foo(myInput);
} catch (IllegalArgumentException e) {
// Where did this come from!?
// It could have come from foo(myInput), or baz(), or bar(),
// or some method that any of them invoked, or really anywhere
// in that stack.
// It could be something totally unrelated to user input, just
// a bug somewhere in my code.
// Handle it somehow...
}
在重要的情况下——例如,您希望弹出一条有用的提示,提示用户不允许在输入表单中输入-1
——您可能希望抛出一个自定义异常,以便以后更容易地捕获它:
try {
baz();
bar();
foo(myInput);
} catch (BadUserInputException e) {
reportError("Bad input: " + e.getMessage());
log.info("recorded bad user input", e);
}
至于checkState
,我觉得这听起来不太合适。该异常通常意味着问题是此
所处的状态(或应用程序中其他更全局的状态)。发件人:
表示在非法或不适当的时间调用了方法
在您的情况下,a-1永远不合适,因此checkState
具有误导性。现在,如果是:
if (x == -1 && (!allowNegativeOne()) { ... }
…那么这就更合适了,尽管它仍然有上面提到的IllegalArgumentException
的缺点
因此,最后一个问题是,您是应该保持
if
的原样,还是使用helper方法。这实际上取决于口味、检查的复杂程度以及使用频率(例如,在其他方法中)。如果检查像x==-1
一样简单,并且该检查从未通过其他方法执行过(因此代码重用不是问题),那么我只保留If
首先需要区分契约(例如断言/编程错误)和错误处理(例如,可以而且应该捕获并从中恢复的可恢复异常)
如果您需要检查中间结果,似乎您不信任被调用的服务,您希望确保您的假设成立。对吗?这应该表示为断言,Guava对此没有很好的支持
看看valid4j。在这里和这里找到的
然后我会这样表达代码(使用valid4j对hamcrest matchers的支持):
这里还有一些很好的答案 根据先决条件: 前置条件异常用于表示调用方法已出错。(…)后置条件或其他不变故障不应引发这些类型的异常 所以 我应该将if(…){…}部分包装在我自己的helper中吗 不,现有的设施应该足够好 还是应该使用番石榴的checkState 可能是:如果在调用该方法之前需要从文件中加载参数,那么这将是该类必须如何使用的契约的一部分 或者我应该将get()的失败视为param的结果并使用checkArgument吗 可能是:例如,如果对参数的语法有一些格式限制。(尽管可能会在
get()
中)
我应该在这些情况下使用资产吗
是的。如果不是像上面那样的先决条件检查,那么通常我会在这里使用一个assert
。别忘了你仍然可以添加一条消息:
assert x != 1 : "Indicates a bug.";
我发现这适合于记录期望并验证类或方法的内部/私有实现
如果你想做一个运行时检查,你可以做
If(…)抛出AssertionError
,但这可能只有在您使用不信任的不可靠代码时才有必要。您的代码检查数据的方式非常有效,但是您可能希望使用比RuntimeException
更“具体”的异常-可能是非法状态异常
,或者您自己的异常之一。通常“这不应该发生“异常应该是AssertionError,而不是RuntimeException。使用assert有点脆弱,因为它依赖于JVM参数……除此之外,您的代码在我看来还不错。使用参数得到-1似乎是一个有效的IllegalArgumentException
,因此我会使用checkArgument。”(x!--1,“我的消息”)
get
只是一个例子,请忽略它的语义,还有checkNotNull
是我希望如果(…)
部分看起来像什么的一个例子,本质上我只是缺少了一个checkorhrowruntime()
assert x != 1 : "Indicates a bug.";