The Beauty and Power of Java Checked Exceptions
Preface
The Checked Exceptions War:
In their attempt to copy Java with the .Net library Microsoft dropped an excellent feature: Checked Exceptions.
They use various arguments to refute the need for checked exceptions like, for large projects Checked Exceptions well, they just don't like them, they
say the throws clause in a method signature adds to the complexity and cuts down the reusability of a method. But, in a large project there's bound to
be method signature changes:
void calcPI( int number )
might change to:
void calcPI( double doubleNumber )
Check Exceptions add a "throws" clause that adds itself as an additional restriction.
void calcPI( double doubleNumber ) throws NumberException
might change to:
void calcPI( doulble doubleNumber ) throws NumberException, IOException
Of couse, this is true, but it's more a hinderance in SMALL projects, because invariably in Large projects something's going to change,
and there's no more perfect example then Microsoft's own Dot Net Libraries:
Why is the current version of Dot Net named "Microsoft Dot Net Framework 1.1 "?
Why isn't it simply "Microsoft Dot Net Framework"? Because in a large library there's going to be sufficient method signature changes to require a Name
Space change.
The real reason seems to me:
Microsoft has never enjoyed a reputation for solid "Mainframe" or "Server" level of quality. Microsoft has never spent the resources or done the testing
required to get to that level of quality. With the Throws clause, an object designer can force the knowledge that errors will occur to the caller of
the class method. Which means the caller Can't Ignore the possibility of errors. The acknologement that errors can occur would be a revolutionary mindset
change at Microsoft. We can see from their handling of the concept of Check Exceptions that that isn't going to occur. But, that's why you buy from
Sun or IBM, in serious domains: Military, HealthCare where real lives are at stake you've got to have the best tools for the job.
IBM's response to this controversy is that only Recoverable Errors should be coded as Checked Exceptions. Since IBM does have a reputation for shipping quality product, this criticism can't be ignored.
Still, I like Sun's position. If I read their position correctly, Recoverable, Important and Exceptions Caught In Testing, should be thrown.
Like the following example: IOException, is generally thought to be an error in which you can not recover. But really, it depends upon the caller.
The IO Error may not be recoverable, but by catching the exception the job can still continue to process. This seems to me to be the "Server Designer"
mentality: "The job must continue to process". This mentality requires more effort, but, allows the job to act in a more professional responsible manner.
This example of catching an IOException, is a bit simplistic, being only an example. This example only throws the exception back to the caller. In the real world the programmer should catch the exception locally, attempt to retry the read, say 10 times, and then throw the exception back to the caller.
What is a Checked Exception:
Simply, let's say you have a problem to program into a solution. No matter how much experience I have I always like to get someone else to discuss the
problem and solution with. ( Using at least one of the steps in Extreme Programming ).
With Java I get "Bill Joy". One of the prime architects of Java, looking over my shoulder, and making comments: "So, you're going to read from a file. You know, you might get an IOException if there's a bad sector in that file". This is extremely helpful advice especially if you don't like getting support calls at 4am. And that's all there is to Checked Exceptions, these are reminders of the most likely errors to occur in software development.
Contrast that to Dot Net. Dot Net has no Checked Exceptions. Microsoft leaves it up the the individual developer to decide what level of quality to program into the application. I've seen some .Net code now, and I can assure you most .Net programmers are programming zero exceptions of any kind. When it comes to a question of quality you have Java on one side giving your programming staff hundreds of reminders of the most likely errors to occur. On the Dot Net side you have Microsoft giving your programmers nothing.
An example, in English, of the Power of Checked Exceptions:
Imagine you work for the FBI and you are charged with writing search code to scan 50 state files in search of a Killer. So you write two classes:
KillerSearch and
KillerSearchManager.
KillerSearchManager builds a list of the 50 state files it will scan. KillerSearchManager also is loaded with the criteria of the search: Blue Eyes, Brown Hair, One Armed Man.
KillerSearchManager starts up a the KillerSearch class passing in the state of Vermont and the Killer characteristics.
KillerSearch starts searching this archive of known criminals for a match.
If it gets a match, the search is done.
If it doesn't get a match, it reports back to KillerSearchManager and KSM passes the next state file.
Here's where JAVA Checked Exceptions come into play.
If while scanning the state of Pennsylvania, KillerSearch receives an IOException, a checked exception in Java, the Java class will stop processing and
REPORT the error to KillerSearchManager, who will Log the error, send an email notification to the responsible owner of this application, and CONTINUE
THE SEARCH.
KSM will then pass the Next State to the KilllerSearch class and the Hunt will Continue.
Later that night KSM finds a match for the killer in the state of California. The CA FBI is emailed the results, they pick up the killer at 5am.
A Dot Net solution will receive the IOException from the state of Pennsylvania and QUIT.
The NEXT DAY, around 8 or 9 am, the Dot Net programmer will read the log file of the KSM and determine how many states were processed, rebuild a new
list of states to process, and start a rerun of the job. The killer will Not be caught. The FBI will look like a bunch of idiots.
So, that's the debate:
- Java gives you Resilient Software, software that takes a hit and keeps running.
Software with a Flak-Jacket on. Java checked exceptions add a little more time to a project ( 1% ) so that the programmer can write code to handle the
likely errors to be encountered.
- Dot Net ( VB or C# ) takes the error and dies, Dot Net goes into battle naked, unarmed and doesn't last long. Dot Net frees the developer of that 1%
penalty up front, only to deliver a 1000% penalty at the back end, that re-occurs again and again as an application runs and encounters unexpected error
after error.
Conclusion:
For a Fortune 2000 company, Java is the only solution, Java has the Mind-Set of the enterprise programmer. To save the enterprise developer as much time
in re-staging a job for re-run as possible. To give the developer the highest quality tools to deliver the highest quality solution.
Dot Net only looks good to the beginner programmer only interested in the "One TRUE Path" through a program. To the programmer living in the imaginary world where no unexpected errors ever occur, where IF statements don't need ELSE clauses, Dot Net is the answer.
Another important point is that in Education: J# is no substitute for Java. If it doesn't have checked exceptions, it's not Java, just a really bad copy.
PICK YOUR POISON
In Business, if you must code in Dot Net then J# looks to be the easiest language to use.
- Object Oriented VB is incredibly WORDY, those people who can't type will just write even worse code now.
- C# looks more and more a language Com programmers will move to, as it's got all their favorite, and unnecessary, interfaces.
- J# is the cleanest, simplest language of the bunch.
Why Programmers with Microsoft Experience Don't Move to Java
From my point of view, it comes down to a Paradigm shift.
Programming that requires a different way of thinking.
Again, a good introductory course to Java should cure this.
But, there have been other paradigm shifts in programming in the past.
The programming language Forth was one of the most severe.
If you've never gone though a paradigm shift you will fear the possiblity that you won't get it.
But, again, Java is one of the smallest paradigm shifts ever in the industry.
It simply requires that you turn Nouns into Objects.
The typical Microsoft programmer, there are exceptions, doesn't spend much time in design.
They rush to the code phase. This is called "Stream of Consciousness" Programming. In other words, the first thing I think of is the first thing
I code. This can lead to simple coding solutions, one method that does everything, that can't be subdivided and handled by multiple programmers. Once
Fred starts down this path, then everyone must wait for Fred to finish.
Object Oriented Design requires a bit more Up Front Thought:
Objective: Order A Book From Amazon.com
Decide on an Object Model: ( Convert Nouns to Objects ):
- Book - StoreCatalog - HttpConnection - CreditCard
- Now, we have 4 classes and we can next decide on class interfaces:
- Interfaces: HttpConnection.Connect(), StoreCatalog.Search(), CreditCard.setInfo(), CreditCard.Purchase()
- Then, we can put four programmers, one on each class, to code the solution.
- Each class can be independently tested.
Simple User Flow / Use Case:
- Make a Connection
- Is Store Up? Yes, continue Else send an invitation to come back later.
- Search Catalog for Book
- If Yes, start the Book Buying Process using CreditCard.
- If No, then Keyword search for books like the original.
The Other Advantage of Checked Exceptions
Other's have pointed out this simple point, Checked Exceptions make great Warning Signs.
When I go to the trouble of designing and testing a class, I write down the problem's and Exceptions I've encountered. On the premise that if I encountered
a MalformedURLException and a ConnectionException while testing, then you can be sure you will also encounter these problems in production, not every
day, but often enough for you to save some serious Time and Money by writing code to handle these conditions.
public void logon( String sUrlBase, String sInUser )
throws MalformedURLException, ConnectionException
{ // code here // }
By coding the throws clause I pass on my experience to You.
You can choose to do nothing with those two Exceptions, but, you can't say I didn't warn you.
Final Conclusion
It really comes down to the goals and mindset of the designer's of the language.
Over and over again Java highlights and encourages a developer to think and write code that can handle real world conditions and keep running.