views:

417

answers:

9

most of the time i will use exception to check for condition in my code, i wonder when is appropriate time to use assertion

for instance,

Group group=null;
try{
 group = service().getGroup("abc");
}catch(Exception e){
  //i dont log error because i know whenever error occur mean group not found
}

if(group !=null)
{
//do something
}

1.can comment on this code and how assertion fit in here or not?
2. i do know that most of the cases, i can just use exception to do checking like above, but i want to know appropriote way to do it "profesionally" =) and when should i use assertion? seem like i never used assertion and only see assertion in unittest

+8  A: 

Out of my mind (list may be incomplete, and is too long to fit in a comment), I would say:

  • use exceptions when checking parameters passed to public or protected methods and constructors
  • use exceptions when interacting with the user or when you expect the client code to recover from an exceptional situation
  • use exceptions to address problems that might occur
  • use assertions when checking pre-conditions, post-conditions and invariants of private/internal code
  • use assertions to provide feedback to yourself or your developer team
  • use assertions when checking for things that are very unlikely to happen otherwise it means that there is a serious flaw in your application
  • use assertions to state things that you (supposedly) know to be true

In other words, exceptions address the robustness of your application while assertions address its correctness.

Assertions are designed to be cheap to write, you can use them almost everywhere and I'm using this rule of thumb: the more an assertion statement looks stupid, the more valuable it is and the more information it embeds. When debugging a program that does not behave the right way, you will surely check the more obvious failure possibilities based on your experience. Then you will check for problems that just cannot happen: this is exactly when assertions help a lot and save time.

Gregory Pakosz
A: 

Depends on what getGroup() is supposed to do. If its API contract says that it should never return null, then use assert.

BalusC
A: 

Testing for null will only catch nulls causing problems, whereas a try/catch as you have it will catch any error.

Broadly, try/catch is safer, but slightly slower, and you have to be careful that you catch all the kinds of error that may occur. So I would say use try/catch - one day the getGroup code may change, and you just might need that bigger net.

Phil H
+3  A: 

Remember assertions can be disabled at runtime using parameters, and are disabled by default http://java.sun.com/javase/6/docs/technotes/tools/windows/java.html, so don't count on it except for debugging purposes.

Also you should read the Sun article about asset to have more cases where to use or not assert

chburd
+5  A: 

Assertions should be used to check something that should never happen, while an exception should be used to check something that might happen. For example, a function might divide by 0, so an exception should be used, but an assertion could be used to check that the harddrive suddenly disapears. An assertion would stop the program from running, but an exception would let the program continue running.

Note that if(group != null) is not an assertion, that is just a conditional.

Marius
+2  A: 

Well, back at Microsoft, the recommendation was to throw Exceptions in all APIs you make available publicly and use Asserts in all sorts of assumptions you make about code that's internal. It's a bit of a loose definition but I guess it's up to each dev to define the line.

Regarding the use of Exceptions, as the name says, their usage should be exceptional so for the code you present above, the getGroup call shoukd return null if no service exists. Exception should only occurs if a network link goes down or something like that.

I guess the conclusion is that it's a bit left down to the dev team for each app to define the boundaries of assert vs exceptions.

ruibm
IMHO, the problem with that kind of recommendation is that it's fine as long as the boundary between the public and private parts of an API is pretty fixed. If you're developing new code then that boundary is often pretty fluid...
Len Holgate
Yes, you're right. It's a guideline but at the end of the day it's left out to the programmers sensitivity. I don't think there's a ultimate defining line for these so I guess you just go with what you think it's right from reading loads of different code.
ruibm
A: 

I confess I'm a little confused by your question. When an assertion condition is not met, an exception is thrown. Confusingly this is called AssertionError. Note that it's unchecked, like (for example) IllegalArgumentException which is thrown in very similar circumstances.

So using assertions in Java

  1. is a more concise means of writing a condition/throw block
  2. permits you to turn these checks on/off via JVM parameters. Normally I would leave these checks on all the time, unless they impact runtime performance or have a similar penalty.
Brian Agnew
AssertionError is a subclass of Error not RuntimeException.
Stephen C
Ah. Of course. I was thinking of checked/unchecked. Now corrected
Brian Agnew
A: 

Unfortunately asserts Can be disabled. When in production you need All the help you Can get when tracking Down something unforeseen, so asserts disqualify themselves.

Thorbjørn Ravn Andersen
+2  A: 

The following code is bad style and potentially buggy

try {
    group = service().getGroup("abc");
} catch (Exception e) {
    //i dont log error because i know whenever error occur mean group not found
}

The problem is that you DON'T know that an exception means that the group was not found. It is also possible that the service() call threw an exception, or that it returned null which then caused a NullPointerException.

When you catch an "expected" exception, you should catch only the exception that you are expecting. By catching java.lang.Exception (and especially by not logging it), you are making it harder to diagnose / debug the problem, and potentially allowing the app to do more damage.

Stephen C