在Java中,强烈建议使用哪个,为什么?两种类型都会抛出异常,因此在这方面处理它们是相同的。 assert稍短一些,但我不确定有多重要。 >

评论

我更喜欢简单的obj.hashCode();-)

#1 楼

谨防!

除非在编译代码时明确指定“启用断言”,否则在运行时将删除断言。 Java断言不应在生产代码上使用,而应限于私有方法(请参见Exception与Assertion),因为私有方法应被开发人员所知并使用。同样,assert会抛出AssertionError,它扩展了Error而不是Exception,并且通常表明您有一个非常异常的错误(例如“ OutOfMemoryError”,很难从中恢复,不是吗?),您不希望能够处理。 br />
删除“ enable assertions”标志,并通过调试器进行检查,您将看到您不会踩IllegalArgumentException throw调用...因为此代码尚未编译(同样, ea”已删除)

最好将第二种构造用于公共/受保护的方法,如果您希望在一行代码中完成某件事,至少我知道一种方法的。我个人使用Spring Framework的Assert类,该类具有一些用于检查参数的方法,并在失败时抛出“ IllegalArgumentException”。基本上,您要做的是:

Assert.notNull(obj, "object was null");


...实际上,这将执行与您在第二个示例中编写的代码完全相同的代码。还有一些其他有用的方法,例如hasTexthasLength

我不喜欢编写多余的代码,所以当我将编写的行数减少2(2行> 1行)时感到很高兴:-)

评论


啊,我忘记断言了!好答案。我会稍等一下,看是否还有其他东西,然后接受:)

–丹妮丝
2012-2-27在19:17

请注意,没有标志可以在编译时删除断言(尽管可以通过条件编译将其删除)。断言默认是在运行时禁用的(我认为JVM将其视为NOOP),但可以通过java -ea和以编程方式启用。 @Jalayn我认为在生产代码中包含断言是完全有效的,因为它们对于在现场进行调试非常有用

–贾斯汀·穆勒(Justin Muller)
2014年1月24日在7:30

@ Jalayn,-1。编译器不会删除断言代码。即使它们不运行,除非您执行cmd java -ea。

–起搏器
14年8月26日在16:15

可以使用Objects.requreNonNull时不需要Spring框架

–含蓄
17-10-10在18:12

#2 楼

您需要使用一个例外。使用断言可能会滥用该功能。

未经检查的异常旨在检测库用户的编程错误,而断言旨在检测自己逻辑中的错误。这些是单独的问题,不应混在一起。

例如,一个断言

此断言确保myConnection已连接;如果上面的代码未能获得有效的连接,则它应该在到达此点之前引发异常或返回。” />
assert myConnection.isConnected();


表示“未建立连接即调用我的库是编程错误”。

评论


这些信息确实有帮助,但是我接受Jalayn的建议,因为它指出了我可能如何使用assert方法引入错误。

–丹妮丝
2012年2月27日在21:43

优点:“未经检查的异常旨在检测库用户的编程错误,而断言旨在检测您自己的逻辑中的错误。这些是单独的问题,不应混在一起。”

–阿西姆·加法尔(Asim Ghaffar)
2013年9月19日在12:41

是的,但这是假设OP正在编写一个库。如果它们的代码仅供内部使用,则可以使用断言。

–user949300
18年4月24日在4:12

#3 楼

如果编写的函数不允许null作为有效参数值,则应在签名中添加@Nonnull批注,并使用Objects.requireNonNull检查参数是否为null,如果存在则抛出NullPointerException@Nonnull注释用于文档说明,在某些情况下会在编译时提供有用的警告。它不会阻止在运行时传递null

void doStuff(@Nonnull Object obj) {
    Objects.requireNonNull(obj, "obj must not be null");

    // do stuff...
}


更新:@Nonnull批注不是Java标准库的一部分。相反,有来自第三方库的众多竞争标准(请参阅我应该使用哪个@NotNull Java注释?)。这并不意味着使用它不是一个坏主意,只是它不是标准的。

评论


感谢您指出Objects.requireNonNull()对我来说是新的。您知道哪里有类似的“ requireTrue()”或“ requireEqual()”方法吗?没有什么反对Spring的断言,但不是每个人都在使用它。

–user949300
17年10月11日,0:01

@ user949300 Objects.requireNonNull()用于参数验证。如果要求一个参数为真或等于某个值,则该参数是没有意义的。对于非法参数以外的错误情况,应引发一个异常,以更准确地描述该错误。也有JUnit声明,但这是用于测试的。

–含蓄
17-10-11在0:15



我想的更像是说平方根函数Objects.requireTrue(x> = 0.0); ,或者对于某些哈希,Objects.requireEquals(hash.length == 256)

–user949300
17年11月19日在20:00

我必须使用哪个@Nonnull? javax.validation.constraints.NotNull吗?

–敏捷
18 Mar 26 '18在8:39

我将使用Eclipse JDT批注,因为它们是由聪明人制作的:)。文档:help.eclipse.org/neon/…-您也可以配置IntelliJ来使用它们。

– koppor
18年7月9日在21:29

#4 楼

我总是更喜欢抛出IllegalArgumentException而不是断言。因此,可能会给其他开发人员以错误的印象,即您的方法是测试方法。这与Java开发人员遵循的Exception Handling约定更加一致。

评论


断言比JUnit早40年左右-向C程序员询问ASSERT宏。

– JBR威尔金森
13年2月22日在22:04



这个问题不是关于c的。关于Java。所以我已经在Java上下文中回答了。

– rai.skumar
13年2月23日在5:43

不要混淆assert(保留关键字)和Assert(JUnit类),它们都用于对变量执行检查,但除此之外,它们是两个截然不同的事物,并且行为也截然不同。

– Newtopian
17-10-11在22:01

#5 楼

我没有使用很多aserts,而是使用Lombock @NonNull的常用方法: NonNull;

public class NonNullExample extends Something {
  private String name;

  public NonNullExample(@NonNull Person person) {
    super("Hello");
    this.name = person.getName();
  }
}


Java版本:

 import lombok.NonNull;

public class NonNullExample extends Something {
  private String name;

  public NonNullExample(@NonNull Person person) {
    super("Hello");
    if (person == null) {
      throw new NullPointerException("person");
    }
    this.name = person.getName();
  }
}


Lombok是一个非常不错的库,我在各处都使用了

#6 楼

IMO第二个稍好一点,因为它带来了更多信息并且可以进一步扩展(例如,通过扩展异常类)以提供更多信息,并且它不使用更容易理解的否定比较。