简体   繁体   English

番石榴的前提条件checkNull,checkArgument

[英]Guava preconditions checkNull, checkArgument

I want to check preconditions on a base class so that I know subtypes will always use constructor arguments that are valid. 我想检查基类上的前提条件,以便知道子类型将始终使用有效的构造函数参数。

Let's take as an example a constructor that: 让我们以一个构造器为例:

  1. takes 2 or more parameters 接受2个或更多参数
  2. takes parameters of different types 接受不同类型的参数
  3. for one parameter, it performs multiple checks (eg String is not null and not empty) 对于一个参数,它执行多次检查(例如String不为null 并且不为空)

How would one best use the Guava preconditions approach in that case? 在这种情况下,如何最好地使用番石榴前提条件方法?

In a mock example like this: (this is contrived!) 在这样的模拟示例中:(这是人为的!)

protected AbstractException(String errorMessage, Throwable errorCause) {
  super(errorMessage, errorCause);
  checkNotNull(errorMessage,
      ErrorMessage.MethodArgument.CANNOT_BE_NULL_CHECK, "errorMessage");
  checkArgument(!errorMessage.isEmpty(),
      ErrorMessage.MethodArgument.CANNOT_BE_EMPTY_STRING_CHECK,
      "errorMessage");
  checkNotNull(errorCause, ErrorMessage.MethodArgument.CANNOT_BE_NULL_CHECK,
      "errorCause");
}

I end up calling super before checking the arguments because a call to super needs to be the first line of the method and, although I could do super(checkNoNull(errorMessage)) , I cannot do the same wrapping using checkArgument because that returns void . 我最终在检查参数之前调用了super ,因为对super的调用需要是方法的第一行,尽管我可以做super(checkNoNull(errorMessage)) ,但是我不能使用checkArgument进行相同的包装,因为这会返回void So the dilemma is: 因此,难题是:

  • Where do I put the checks on all arguments? 我应该在哪里检查所有参数? I don't want to create a Builder just for that 我不想为此创建一个生成器
  • How do I "group" checks as in a fictitious checkStringNotNullAndNotEmpty() 我如何像虚拟的checkStringNotNullAndNotEmpty()一样“分组”检查
  • Should I rather think about integration with matchers frameworks? 我是否应该考虑与匹配器框架集成? (hamcrest, fest assertions...) (hamcrest,fest断言...)

I use the odd-looking ErrorMessage.MethodArgument.CANNOT_BE_NULL_CHECK because the default throw does not include an error message so from the testing side I cannot recognise this as an argument validation failure rather than a "any" NPE? 我使用外观怪异的ErrorMessage.MethodArgument.CANNOT_BE_NULL_CHECK,因为默认throw不包含错误消息,因此从测试方面,我无法将其识别为参数验证失败,而不是“任何” NPE?

Am I doing it all wrong? 我做错了吗?

This should have been a comment, but it's too long. 这本来应该是一个评论,但是太长了。

  • Calling super before the test is harmless provided that the super ctor doesn't do things which it shouldn't do anyway . 如果超级控制器不会做它不应该做的事情, 那么在测试前调用super是无害的。
  • It could be prevented via a static builder method, you need no Builder. 可以通过静态构建器方法来防止它,您不需要构建器。 But it's not worth it. 但这不值得。
  • I doubt that grouping tests is generally useful; 我怀疑分组测试通常很有用; if it was, then there would be a such method already. 如果是这样,那么已经有这样的方法了。 But if you need one such a concrete thing more than twice, then write your own; 但是,如果您需要两次以上这样的具体事情,请自己编写; if it comes often, report it to the Guava team as an RFE. 如果经常出现,请将其作为RFE报告给番石榴团队。
  • I'm pretty sure, matchers are an overkill here as you're just creating an exception, ie, something used only rarely (I hope). 我很确定,匹配器在这里是一个过大的杀伤力,因为您只是在创建一个例外,即,很少使用的东西(我希望)。 As your test is runtime only, it can't really help to catch errors. 由于您的测试仅是运行时,因此并不能真正帮助您捕获错误。 It would be nice, if you could statically ensure a "properly" constructed exception, but it's impossible in pure java. 如果可以静态地确保“正确地”构造的异常,那将是很好的,但是在纯Java中这是不可能的。

More important: The exceptions you're throwing are probably inferior to the ones you'd get without all the checks. 更重要的是:您抛出的异常可能不如没有所有检查的异常。 Imagine the user provides a cause and no message. 假设用户提供了原因,但没有消息。 That's bad, you think, but you replace it with an NPE lacking any cause. 您认为这很糟糕,但是您可以使用没有任何原因的NPE替换它。 That's worse. 更糟

Look at Guava's Preconditions.format (package private). 查看Guava的Preconditions.format (私有包)。 They could check the correct number of arguments first, but they do not. 他们可以先检查正确数量的参数,但不能。 You can provide too few or too many, which is an error, but ignoring it is the best way to handle it. 您可以提供太少或太多,这是一个错误,但忽略它是处理它的最佳方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在将番石榴升级到最新的23.5时,获得NoSuchMethodError作为Preconditions.checkArgument - On upgrading Guava to the latest 23.5 getting NoSuchMethodError for Preconditions.checkArgument 为什么Google Guava Preconditions的checkArgument没有返回值? - Why doesn't Google Guava Preconditions's checkArgument return a value? Firebase管理员SDK:IllegalArgumentException,Preconditions.checkArgument - Firebase admin sdk: IllegalArgumentException, Preconditions.checkArgument Guava Preconditions的自定义异常 - Custom exception with Guava Preconditions Guava前提条件RuntimeExceptions处理 - Guava Preconditions RuntimeExceptions handling 摇篮罐不包含番石榴前提条件 - Gradle jar does not include Guava Preconditions NoSuchMethodError: com.google.common.base.Preconditions.checkArgument(ZLjava/lang/String;CLjava/lang/Object;)V - NoSuchMethodError: com.google.common.base.Preconditions.checkArgument(ZLjava/lang/String;CLjava/lang/Object;)V 错误:原因:com.google.common.base.Preconditions.checkArgument(ZLjava / lang / String; Ljava / lang / Object;)V - Error:Cause: com.google.common.base.Preconditions.checkArgument(ZLjava/lang/String;Ljava/lang/Object;)V java.lang.NoSuchMethodError: com.google.common.base.Preconditions.checkArgument - java.lang.NoSuchMethodError: com.google.common.base.Preconditions.checkArgument com.google.common.base.Preconditions.checkArgument(ZLjava /郎/字符串; CLjava /郎/对象;)V - com.google.common.base.Preconditions.checkArgument(ZLjava/lang/String;CLjava/lang/Object;)V
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM