There are always exceptions to the rule, right? In Java, those exceptions allow a clean break from normal program flow in the event of an exceptional situation. They’re not used for program flow interruption, but for program flow branching, which can sometimes lead to difficult-to-maintain code. Marcus Zarra walks you through several best practices for using exceptions in Java.
try {
PostComment(“osnews.com”);
status++;
} catch(TrollException ex) {
System.out.println(ex.toString();
mod–;
} catch(FlameBaitException ex) {
System.out.println(ex.toString();
mod–;
} catch(OSNewsBrokeException ex) {
Stuff.Happens.CallJanitor();
}
Merry Christmas to all from Smallvue.com!
Exceptions are one of the best things that have happened in java. The other thing being automatic garbage collection. This does away with the memory leaks that used to be there when we used to code in C++.
In my opinion, these two – exceptions and automatic memory management (garbage collection) are the two most popular features of java language.
GC? you can have memory leaks with garbage collection. For example, there’s (was?) a memory leak in Apache’s multipart form decoding Java libraries that caused Tomcat to die after a few (millions) of HTTP POSTs. Again, it’s not bullet proof.
Exceptions… with great power comes great responsability , in other words, use them carefully … sorry, I couldn’t resist ๐
An interesting read:
http://www.joelonsoftware.com/items/2003/10/13.html
This guy says that exceptions are no better than goto’s, and I tend to agree, code becomes harder to understand and maintain if exceptions aren’t used properly.
Regards,
Carlos
don’t use exceptions. avoid them. (c++ zen proverb)
I hope you realize that the term “c++ zen” is an oxymoron .
noooo
While C++ exceptions are probably a bit troublesome with the way they are implemented, Java exceptions are unproblematic when compared to them.
Can you describe, what’s wrong with C++ exceptions? And why Java exceptions are unproblematic compared to them?
Can you describe, what’s wrong with C++ exceptions? And why Java exceptions are unproblematic compared to them?
For course he can’t explain it. It’s just fokelore that he heard some one say, or read some where, now he is repeating it…
> Can you describe, what’s wrong with C++ exceptions? And why Java exceptions are unproblematic compared to them?
Nested exceptions? A nightmare. For example,
class A {
public:
A() { … }
~A() { if (C1) throw E1; }
…
}
void foo()
{
A a;
…
if (C2)
throw E2;
}
if condition C2 is true, then exception E2 is thrown, and this causes A’s destructor to be called while the excepting is “unwinding” the call stack. If condition C1 in A’s destructor is also true, then… KABOOM!!! Your application dies hard ๐
There’s a large C++ application written (by someone else at my company) with these pitfalls. It has been a nightmare to fix these issues.
Regards,
Carlos
It’s your coworker fault, and actually C++ notifying you that programming error is a feature . Throwing exceptions in a C++ destructor it’s generally a bad programming practice (exceptions thrown in Java finalizers are simply ignored, that should give you an idea).
http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.3
OTOH, throwing E1 in a finally block during stack unwinding, will swallow E2 silently. You’ll end up handling (or maybe ignoring) an exception that it’s not the cause your code doesn’t work.
public class Main {
void doSomething() throws Exception {
throw new Exception(“i know why it does not work”);
}
void throwIt() {
throw new RuntimeException(“i have no idea why it does not work”);
}
void run() throws Exception {
try {
doSomething();
} finally {
throwIt();
}
}
public static void main(String[] args) throws Exception {
new Main().run();
}
}
C++ job is far better pointing you bad exception handling than Java.
try {
…
}
catch(Exception ex) {
if(ex instanceof IOException) {
…
}
else if(ex instanceof SQLException) {
…
}
…
}
just thought of it, never tried it yet.. maybe to avoid nested catch statements and make it much more readable
Is that really more readable than:
try{
…
}catch(IOException e){
…
}catch(SQLException e){
…
}finally{
…
}
— IMHO, the above is actually more readable than what I seem to read in the article:
try{
…
}catch(ComplicatedException e){
if(needToKnowMoreInformation){
Exception e2=e.getCause();
if(e2 instanceOf SQLException){
…
}else if(e2 instanceOf IOException){
…
}
}
}finally{
…
}
I agree entirely with you, but if you want your code to be as readable as possible, why not put the braces on lines of their own?
Isn’t the whole point of C snytax based languages to be as hard to read as possible?
“I agree entirely with you, but if you want your code to be as readable as possible, why not put the braces on lines of their own?”
Well, probably because that isn’t necessarily the case. People look at code through their own filters. I despise braces on their own lines. I don’t think it makes it more readable at all.
The idea of putting braces on new lines was taking hold amongst C and C++ programmers until Java and JavaScript came along – now it seems to have reverted back to standard practice again.
I find it a pain to see braces starting on the same line as other code. That whole style only really came into use to make maximum use of old terminal displays.
It really is how you look at the code. BSD/GNU styles make it easy to match the syntax of brackets, while K&R makes it easy to match the semantics of brackets.
I look at brackets all alone on a line and I really do think that it is wierd looking, almost incomplete.
I generally write in GNU style, but I really do think K&R style makes more sense even today.
It doesn’t matter how many lines you can display on your screen, you still want to maximize (without losing readability) the amount of logic you can see on the screen at once. Many will say that if you have a block that’s smaller than a function which you can’t see all of in one screen, then it needs to be broken up somehow.
I can pretty easily recognize if, while, for, etc as the beginning of a block and don’t need the ‘{‘ to show it to me.
Of course, you could always use a language which doesn’t have block begin and end characters . But I suppose that’s out of the scope of this discussion.
I think someone else commented on this out-of-thread, but I think brace location is a matter of opinion. I used to put braces on their own line — I wanted to line up the “beginning” of the block with the end. But since then I have come to look at the “beginning” of a code block to be the initial instruction operating on the brace-block, not the brace-block itself. So, now it makes more sense to me to line up the closing brace with the instruction that starts the code-block, not the opening brace.
Just my $0.02,
dotMatt
Merry Christmas everyone, for the good post and OSNEWS.com for bringing me hear everyday, multiple times too.
Here’s a little animation for ye all. It’s still a work in progress…….next year it will have sound and be slower,,,,,,,my humor in Macromedia Flash to you all!
http://img484.imageshack.us/my.php?image=de5my.swf
ken
ummm…..Ken……what does that havet o do with anyhting? clearly the reindeer in your animation are not powerd by java. as them seem far to unstable (what with the exploding at all).
What the big deal about Actionscript 2.0?
Actionscript 2.0, introduced in Macromedia Flash MX 2004 has dramatically improved it’s approached to inheritance, encapsulation, and polymorphism. With syntax similar to the Java language, Actionscript can only now call itself a reall object oriented language.
Poundsmack, Actionscript inside flash is similar to Java. Most web developers need to know both now. At least that’s what’s on a lot of recruiting sites. Ken
The very first example advocates using a boolean return value on a method that does complex work. Specifically, it advocates returning false if the customer’s credit card cannot be charged. That’s an exception! If the method was called “attemptToChargeCustomer” it would be acceptable to return true on success and false on failure, but it isn’t. The method is called “chargeCustomerCard” and that’s what it should do. If it can’t do what its name says it will then an exception has occured and the caller should be free to catch it or pass it up. Stupid article written by a stupid person.
“Stupid article written by a stupid person.”
Wow, spoken like a true scholar, I am right, anyone who thinks different is stupid.
I believe you are wrong. It’s a pretty good article, not perfect, but hardly “stupid.” It’s not an article about good naming convention, it’s about exceptions. And even so, some people would disagree with your naming convention. I think your working with the wrong language (Java) if you want all your statements to equate to perfectly logical English sentences. I wouldn’t want my code overrun with function names like “attemptToChargeCustomerCard.” “chargeCustomerCard” adequately describes the purpose function. The function name doesn’t need to hint at how it works. Javadoc comments should describe the return value and any possible exceptions, not the function name. Lets say we do it your way
if (attemptToChargeCustomer()) {…} else…
It’s still ambiguous. Does false mean we couldn’t contact their bank or that it was denied. Do exceptions occur when we can’t contact the bank? We still need to double check the Javadocs(api docs) to see what false means exactly and what exceptions could arise.
“it advocates returning false if the customer’s credit card cannot be charged. That’s an exception! If the method was called “attemptToChargeCustomer” it would be acceptable to return true on success and false on failure, but it isn’t.”
His use of a return value is good design with either function name. An exceptional event is “anything that is outside of the expected scope.” Not charging the card is a completely possible outcome, its not an exception!
a good example from the article
In this context, I define an exceptional event as anything that is outside of the expected scope. If you are verifying the results in a text field, and the text field requires only numbers, a letter is not an exceptional result. That should be expected behavior. Wrong, but expected. In this situation, it is better to return an error code instead of throwing an exception.
If the situation is completely unrecoverable, it is proper to throw an exception. What is considered unrecoverable? It naturally depends on the situation, but in some cases, disk errors or network failures would be good places for the use of an exception.
Edited 2005-12-26 06:12
The author is trying to make the point that you shouldn’t use exceptions to branch your code, but to handle serious errors.
I think the idea is that chargeCustomerCard failing is a realistic event that the programmer needs to deal with to run his easy set of tests. This:
if (!chargeCustomerCard()) {
….
}
Is a lot prettier than this:
try {
chargeCustomerCard();
}
catch (Exception e) {
…
}
It’s simply far easier to read. Especially if you have a function which makes 12 of these types of calls with many of them nested. Nested try/catch blocks aren’t pretty to read.
Well, it is more the way they are implemented. C++ exceptions are a nightmare to implement (as in for example, in a kernel). You could try to link against the right libs from gcc – but those at least can have some dependencies on other functions.
While writing a VM that interprets (where I’m on atm, and again kernel mode), it seems for Java code a good deal easier.
The proposed code is uglier than what it pretends to replace.
On the other hand, it replaces it in a more fragile and error prone way.
And the preplaced code is really *bad* java. In fact, it looks like C++ written in Java.
Those who donยดt know errno are doomed to reinvent it.
Those who actually know errno run like hell.
Correct me if I’m wrong, but isn’t the problem with C++ exceptions is related to the fact that C++ has no garbage collection? If an exception is thrown, there is no chance to free allocated memory.
You can create wrapped pointers that free themselves in their deconstructors, but that’s a real pain.
Garbage collection only manages memory. Other resources (files, network connections, database connections, etc) must be released explicitly (and in most cases deterministically).
You can’t rely on the garbage collector calling the ‘finalize’ method to release those resources. As an example, if an exception occurs while manipulating a record on a database with exclusive access, the record will be blocked until the object managing the locking is collected, which is unnaceptable.
To solve this problem, Java uses the ‘try-finally’ construct, which is such a PITA that C# has the ‘using’ sintactic sugar, and IMHO this is still worse than RAII with automatic objects such as auto_ptr.
And still there is the ‘double-fault’ problem: a exception is thrown outside the ‘finally’ block hiding a surely more important exception thrown in the ‘try’ block.
Adding the fact that you still can use a garbage collector for C++, I should say you’re wrong.
when you declare that a function throws an exception, there is no forced checking. And infact once you have done this, it is impossible to exception that is not in the list, but is thrown. This makes code a nightmare.
Java exceptions aren’t perfect and idiots can still write bad code with them. But I would strongy argue that they are a good feature.
In terms of exception usage C++ has a big advantage over Java. Since C++ supports distinct stack allocations you can write clever objects which do the error handling – unlocking mutexes, free allocated memory, … – for you on destruction time within a try-catch block. Well, Java has garbage collection but this does not include automatic prevention of other kinds of “resource leaks” if you don’t perform precise error handling in case of an exception. The creators of the C# language seemed to be aware of this shortcoming in Java and integrated semi stack allocations into the C# language syntax.
Just my 2 cent…
Yes, C# learned from Java’s mistakes – and also didn’t repeat the mistake of checked exceptions.
Reading Anders Hejlsberg’s opinion on checked exceptions, some people extract one fundamental reason in favor of removing the checked exceptions.
Anders Hejlsberg: [http://www.artima.com/intv/handcuffs.html]
“The concern I have about checked exceptions is the handcuffs they put on programmers. You see programmers picking up new APIs that have all these throws clauses, and then you see how convoluted their code gets, and you realize the checked exceptions aren’t helping them any. It is sort of these dictatorial API designers telling you how to do your exception handling. They should not be doing that.”
Other reasons listed are versioning pitfalls and scalability. Proper design of method exception specification, removes these “limitations”; improper design, has an amplifying effect.
Many people prefer a strict model for handling exceptional conditions, as it promotes good code. Readability is not hampered by proper use of checked exceptions, and proper class design plays an important role.
Anders has his opinion, and Java designers are entitled to one as well.
I would not be so quick to dismiss opinion of the Java designers.
As a developer, it is a plus when API provides proper exception specification, as it facilitates a more defined behaviour.
Good comments on unchecked exceptions. Here’s another essay on the subject by Bruce Eckel.
I’ve hated unchecked exceptions from day one. They aren’t scalable and I hate how the interface includes the exceptions…. everytime I add a new exception type it breaks the interface. Terrible idea…
Interface breakage applies to checked exceptions; unchecked exceptions do not require interface specification. (i.e: RuntimeException)
However, interface breakage also happens when developer adds/removes a method parameter, overloads/deprecates previous method. Point is, if API is going to change, programmers should be aware of it, regardless of what caused the change.
Important to emphasize, that interfaces designed correctly, put no more burder on the developer wrt interface breakage than any other update measure taken by the creator of the API.
In practice, properly designed interfaces present checked exceptions as the least changing property throughout the progression of the API.
If used right, checked exceptions promote quality.
For every developer who abuses checked exceptions facility by catching and doing nothing, there are many developers who use exceptions correctly.
opps! I meant I hate checked exceptions.
My point was that exceptions should not be part of the interface. In a complex system, there could be dozens of exceptions that trickle up. Why pollute the interface listing them?
Checked exceptions lead to either 1) catching and rethrowing under a generic exception (which defeats the purpose) or 2) having every method end up throwing Exception (which defeats the purpose again)
> Checked exceptions lead to either 1) catching and
> rethrowing under a generic exception (which defeats the > purpose) or 2) having every method end up throwing
> Exception (which defeats the purpose again)
If this how one uses exceptions then yes, perhaps there is an argument to be made. Real reason why interface throws clause is important, is it lets the developer know which potentially exceptional conditions may occur during called operation, with it carrying appropriate context. Said context can be used to at the very least to record context-sensitive failure information, or at best, attempt to recover using the provided context information.
James Gosling briefly discussed positives of checked exceptions here:
http://www.artima.com/intv/solid.html
Does anyone else go crazy when people completely misuse the phrase “to beg the question”?
From TFA:
“In this example, the catch block is used instead of a false result from the chargeCustomerCard() method. Of course, this begs the question, what happens if the chargeCustomerCard() throws a “real” exception? How is that handled?”
Of course, this doesn’t beg the question at all. If anything, this RAISES the question, or how about you just stop trying to use fancy phrases and just _ask the darn question_?
When one begs the question, one makes a conclusion from premises who contain the conclusion within them. For example, “I believe in God because I believe what was written in the Bible, and the Bible is written by God.”
Furthermore, I don’t quite understand the point of this article. The author gives lots of reasons for using exceptions, all of which are wrong. Some of his tips are right, if obvious (like actually doing something in the catch block–duh). Exceptions are a very simple mechanism meant to work around the following problem:
How do you “chain up” error conditions to a calling method if the error occurs more than one function deep?
That is to say, if sql_open() calls sql_connect() which calls tcp_connect(), and tcp_connect runs into an error, how will sql_open know that the error occured in tcp_connect and not in sql_connect?
In other words, exceptions provide a mechanism for passing an error condition all the way up the call stack, to the original caller and to every caller in between, allowing handling and clean-up to occur at every layer of the code. That’s all. It’s not really that complicated and there shouldn’t be any “rules of thumb” necessary. You should always use exceptions if the error you are running into means that your method didn’t meet its postcondition requirements, so that every layer above your method can adjust for that.
I think the whole problem is treated very nicely in Haskell. The whole discussion about exceptions vs. return values doesn’t arise because
1) return values can in a simple way contain more information than a single number. Java can do this by returning objects, but it’s very cumbersome in comparison (Java is missing bounded subtyping and pattern matching as in Haskell’s algebraic datatypes, so you’d spend a lot of time simulating this in every return-value-class).
2) exception propagation patterns can be factored out into monads in many cases
It’s at least a source of some inspiration for Java programmers, if nothing more. I found this part of Haskell to save me a lot of coding, and it catches a lot of bugs at compile-time.
– Morin
> Does anyone else go crazy when people completely misuse
> the phrase “to beg the question”?
When folks mis-use that term, it shows that they don’t even care enough to understand what they’re writing.
http://en.wikipedia.org/wiki/Beg_the_question
Error codes are like untyped exceptions. Worse, nobody forces you to do anything with them. So as a rule of thumb, if the handling of whatever situation has arisen is not optional, use an exception to make sure that the situation is handled. If you use an errorcode, somebody will not read the javadoc and introduce a bug by not properly testing the output of the method.
Thinking in terms of integer errorcodes and if statements is a clear sign you might want to read up on some design patterns. Proper OO design can provide you with some nice alternatives to the C/C++/VB idiom some programmers bring with them.
Take for example the apache httpclient library. When you do a connect, the http status is not in the returntype. Instead there’s a nice getStatus method which you call on the HttpMethod object. That’s a subtle difference but it makes the client code more explicit because now you have to ask for the status to get it. Similarly there’s methods for accessing the returned headers, getting an inputstream for the content, etc. The connect method either connects or throws an exception.
Your example of not returning error codes with the method call, but having a separate method to call to get the status does nothing to force people to do anything with an error condition. I can agree that if you execute a method without an error return code, it had either better only succeed, or throw an exception. However, this should only happen (for the sake of bending over backwards with exception-happy code, regardless of what language) with something that’s assumed and expected to always work, where failure is a truly bizarre thing: doing a connection to an HTTP server doesn’t qualify as something where that seems extremely rare.
What separating out status into requiring an external status returning method does gain you, however, is a much quieter running of static code checking tools, such as Lint for C/C++, or whatever it may be for other languages.
Where you need more complex information regarding an error condition returned, C++ (and even C using pointers to objects) allows you to pass in a complex object and modify it as required: this doesn’t need to be returned via the return parameter, but I suppose you could argue that it ends up requiring an extra object that’s created when you don’t otherwise care to know about something that rarely happens. The counterargument to that case, though, is that any error condition that can happen should be handled properly, and anyone that ignores a returned value (whether by throwing an exception, returning data by updating an object passed by value, or a regular return value, or having a separate method reserved for checking the error status) simply is negligent in their design and implementation, and their software will go splat when something unexpected happens.
Where you aren’t likely to get away with having a separate method being required to get the current object status is when you’re dealing with objects shared between threads: this is a case where you need proper threading context of an error condition to know whether the current success/failure of something happened from what you were just doing, otherwise you may have a race condition, depending on the locking semantics of the object.
Jonathan Thompson
C++ garbage collection is still a burden when compared to Java and C#’s garbage collection.
Exceptions are just another example on how object oriented languages introduce many non-orthogonal concepts into a language for no good reason at all.
A language that is simple and orthogonal should have only one way to pass information back from a function: a return value. To return complex stuff, it should be possible to return tuples ,complex structures or different types efficiently. But having two distinct mechanisms to return something from a function is just plain stupid.
Using functional language constructs like pattern matching, it is easy to handle exceptional return values elegantly without introducing a completely new concept.
wow. I’m glad you don’t work for my company.
Exceptions have saved my ass so many times… return values are a complicated disaster. Hence exceptions were created.
You should not use exceptions for returning values.
Sorry, but the problem here is that your C++ sucks ๐