简体   繁体   English

我们应该在Java中断言每个对象创建吗?

[英]Should we assert every object creation in java?

Sounds like a stupid question with an obvious answer :) 听起来像个愚蠢的问题,答案很明显:)

Still I've ventured to ask just be doubly sure. 我还是冒险提出只是确定无疑的问题。

We are indeed using asserts like given below 我们确实使用了下面给出的断言

ArrayList alProperties = new ArrayList();

assert alProperties != null : "alProperties is null";

Problem is that making a small & simple document to follow, on asserts is difficult. 问题在于,要根据断言制作一个小的简单文档很困难。 There are many books on asserts, but ideally I like to give a new programmer very simple guidelines on using something like asserts. 有很多关于断言的书,但理想情况下,我想给新程序员提供有关使用断言之类的非常简单的指导。 Btw, does some tool like pmd check for proper usage of asserts? 顺便说一句,像pmd这样的工具是否检查assert的正确使用?

Thanks in advance. 提前致谢。

There's no sane reason to use asserts like that. 没有理智的理由使用这样的断言。 If the object won't be created for some reason, your assert won't even be reached (because an exception was thrown or the VM exited, for example) 如果由于某种原因无法创建对象,则甚至不会达到您的断言(例如,因为引发了异常或退出了VM)

There are some fairly concise guidelines on using assertions in Sun's Programming with Assertions . 在《 Sun的带断言编程》中有一些使用断言的相当简洁的指南。 That article advises that asserts should be used for things like Internal Invariants, Control-Flow Invariants, and Preconditions, Postconditions, and Class Invariants. 该文章建议断言应用于诸如内部不变量,控制流不变量以及前提条件,后置条件和类不变条件之类的事情。

No , you don't want to check object creation. 不,您不想检查对象的创建。

If the object creation fails, the jvm will throw an OutOfMemoryError, and if that happens you're likely to be screwd beyond repair anyway. 如果对象创建失败,则jvm将抛出OutOfMemoryError,并且如果发生这种情况,您无论如何都可能无法修复。

that's like not trusting the JVM. 就像不信任JVM。 Concerning what you take as a given, you got to draw a line somewhere... 关于给定的东西,你必须在某处画一条线...

In Java each call to new returns either a non-null reference to the new object or raises an Exception or an Error. 在Java中,对new的每次调用都返回对新对象的非null引用,或者引发Exception或Error。 In the first case your assert is true, in the second case the assert will not be reached, because you end in the next matching catch-block. 在第一种情况下,您的断言为true,在第二种情况下,将不会达到该断言,因为您将在下一个匹配的catch块中结束。

This assert tests if your Java-implementation is broken and in this case you can't even rely on the assert. 该断言测试您的Java实现是否中断,在这种情况下,您甚至不能依赖该断言。 So I would not make such asserts. 因此,我不会做出这样的断言。 Use assert for restrictions on objects, that aren't enforced by the language (for instance, if your method is passed a parameter that is null but shouldn't be). 使用assert来限制对象,这些对象不是语言所强制执行的(例如,如果您的方法传递了一个参数,但该参数为null而不应该是)。

This assert only clutters your code, it would be equivalent to this assert: 该断言只会使您的代码混乱,它等效于以下断言:

boolean a = true;
assert a : "A should be true"

You shouldn't be testing your JVM, unless that's the point of your program (say, it's a test suite for a JVM you are making). 除非那是程序的重点,否则您不应该测试JVM(例如,这是您要制作的JVM的测试套件)。 Instead you should be testing your pre-conditions, post-conditions and invariants. 相反,您应该测试前置条件,后置条件和不变式。 Sometimes these tests are too basic or too expensive. 有时这些测试太基础或太昂贵。

Pre-conditions probably should only appear at the start of a method (if your have very long methods, then you should break that method into small parts, even if they are all private). 前提条件可能只应出现在方法的开头(如果您的方法很长,则应将该方法分成小部分,即使它们都是私有的)。

Post-conditions should make it clear what you have returned to the caller, you don't test that the sqrt function just returned the sqrt, but you might test that it was positive to make it clear what you are expecting (perhaps later code uses complex numbers and yours is not tested for that). 后置条件应使您清楚返回给调用方的内容,而不是测试sqrt函数是否刚刚返回了sqrt,但可以测试确定期望的内容是肯定的(也许以后的代码会使用复数,您的数字尚未经过测试)。 Instead leave a comment at the bottom. 而是在底部留下评论。

Invariants also often can't be tested, you can't test that your current solution is the correct partial solution (see below) -- though this is one of the nice things about writing things with tail-recursion. 不变式通常也无法测试,您无法测试当前的解决方案是否是正确的部分解决方案(请参阅下文),尽管这是用尾递归编写事物的好方法之一。 Instead, you declare the invariant with a comment. 而是用注释声明不变量。

If you are calling things externally, you would also use an assert, for instance in your example if you had ArrayList.Create() , then you might choose the assertion check for null . 如果在外部调用事物,则还可以使用一个断言,例如,在示例中,如果您具有ArrayList.Create() ,则可以为null选择断言检查。 But only because you don't trust the other code. 但这仅仅是因为您不信任其他代码。 If you wrote that code, you could put the assertion (comment or otherwise) in the factory method itself. 如果编写了该代码,则可以将断言(注释或其他方式)放入工厂方法本身。

int max(int[] a, int n) {
  assert n <= a.length : "N should not exceed the bounds of the array"
  assert n > 0 : "N should be at least one"

  // invariant: m is the maximum of a[0..i]
  int m = a[0];
  for( int i = 1; i < n; n++ ) {
    if( m < a[i] )
      m = a[i];
  }

  // if these were not basic types, we might assert that we found
  // something sensible here, such as m != null
  return m;
}

I'm not sure of complete understand your question but i think that assertions of that kind aren't neccesary. 我不确定是否完全理解您的问题,但是我认为这种主张不是必须的。

When you create an instance, if the program flow continue, the instance isn't a null reference. 创建实例时,如果程序流程继续,则该实例不是空引用。

You want ASSERTS to check properties or invariants of your program. 您希望ASSERTS检查程序的属性或不变式。 A good document to teach this should encourage the programmer to think about such properties in a systematic/methodical manner. 一个好的教学方法应该鼓励程序员以系统/方法的方式考虑这些特性。

if the assert fails, believe me, you're going to have bigger problems than just dealing with the assert. 如果断言失败,请相信我,与处理断言相比,您将遇到更大的问题。

If that assert fails I think it's time I look for another job because the computer is not behaving how it's supposed to and when that happens all hell is going to break loose! 如果断言失败了,我想是时候该找另一份工作了,因为计算机没有按照应有的方式运行,发生这种情况时,一切都会崩溃!

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM