tags:

views:

392

answers:

9

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?

Thanks in advance.

+19  A: 

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)

Jorn
Unless there is a lot of code between the 'new' and the 'assert', which may modify 'alProperties'.
Liran Orevi
Sure. But there isn't any code between it in the example, and even if there was, I don't think an assertion would be the way to go.
Jorn
+1  A: 

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.

HyLian
A: 

You want ASSERTS to check properties or invariants of your program. A good document to teach this should encourage the programmer to think about such properties in a systematic/methodical manner.

badkya
+3  A: 

that's like not trusting the JVM. Concerning what you take as a given, you got to draw a line somewhere...

raoulsson
... and not trusting yourself. At development time you should have tests to tell you when you make mistakes. Then, at runtime, you should be confident in your code that is well written - unless proven otherwise.
Mercer Traieste
+6  A: 

There are some fairly concise guidelines on using assertions in Sun's Programming with Assertions. That article advises that asserts should be used for things like Internal Invariants, Control-Flow Invariants, and Preconditions, Postconditions, and Class Invariants.

Bill the Lizard
+4  A: 

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.

nos
A: 

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!

Michael Wiles
+3  A: 

In Java each call to new returns either a non-null reference to the new object or raises an Exception or an 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.

This assert tests if your Java-implementation is broken and in this case you can't even rely on the assert. 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).

Mnementh
+3  A: 

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). 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). 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. 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;
}
Adam Luter