Why are Exceptions not Checked in .NET? - java

I know Googling I can find an appropriate answer, but I prefer listening to your personal (and maybe technical) opinions.
What is the main reason of the difference between Java and C# in throwing exceptions?
In Java the signature of a method that throws an exception has to use the "throws" keyword, while in C# you don't know in compilation time if an exception could be thrown.

In the article The Trouble with Checked Exceptions and in Anders Hejlsberg's (designer of the C# language) own voice, there are three main reasons for C# not supporting checked exceptions as they are found and verified in Java:
Neutral on Checked Exceptions
“C# is basically silent on the checked
exceptions issue. Once a better
solution is known—and trust me we
continue to think about it—we can go
back and actually put something in
place.”
Versioning with Checked Exceptions
“Adding a new exception to a throws
clause in a new version breaks client
code. It's like adding a method to an
interface. After you publish an
interface, it is for all practical
purposes immutable, …”
“It is funny how people think that the
important thing about exceptions is
handling them. That is not the
important thing about exceptions. In a
well-written application there's a
ratio of ten to one, in my opinion, of
try finally to try catch. Or in C#,
using statements, which are
like try finally.”
Scalability of Checked Exceptions
“In the small, checked exceptions are
very enticing…The trouble
begins when you start building big
systems where you're talking to four
or five different subsystems. Each
subsystem throws four to ten
exceptions. Now, each time you walk up
the ladder of aggregation, you have
this exponential hierarchy below you
of exceptions you have to deal with.
You end up having to declare 40
exceptions that you might throw.…
It just balloons out of control.”
In his article, “Why doesn't C# have exception specifications?”, Anson Horton (Visual C# Program Manager) also lists the following reasons (see the article for details on each point):
Versioning
Productivity and code quality
Impracticality of having class author differentiate between
checked and unchecked exceptions
Difficulty of determining the correct exceptions for interfaces.
It is interesting to note that C# does, nonetheless, support documentation of exceptions thrown by a given method via the <exception> tag and the compiler even takes the trouble to verify that the referenced exception type does indeed exist. There is, however, no check made at the call sites or usage of the method.
You may also want to look into the Exception Hunter, which is a commerical tool by Red Gate Software, that uses static analysis to determine and report exceptions thrown by a method and which may potentially go uncaught:
Exception Hunter is a new analysis
tool that finds and reports the set of
possible exceptions your functions
might throw – before you even ship.
With it, you can locate unhandled
exceptions easily and quickly, down to
the line of code that is throwing the
exceptions. Once you have the results,
you can decide which exceptions need
to be handled (with some exception
handling code) before you release your
application into the wild.
Finally, Bruce Eckel, author of Thinking in Java, has an article called, “Does Java need Checked Exceptions?”, that may be worth reading up as well because the question of why checked exceptions are not there in C# usually takes root in comparisons to Java.

Because the response to checked exceptions is almost always:
try {
// exception throwing code
} catch(Exception e) {
// either
log.error("Error fooing bar",e);
// OR
throw new RuntimeException(e);
}
If you actually know that there is something you can do if a particular exception is thrown, then you can catch it and then handle it, but otherwise it's just incantations to appease the compiler.

The basic design philosophy of C# is that actually catching exceptions is rarely useful, whereas cleaning up resources in exceptional situations is quite important. I think it's fair to say that using (the IDisposable pattern) is their answer to checked exceptions. See [1] for more.
http://www.artima.com/intv/handcuffs.html

By the time .NET was designed, Java had checked exceptions for quite some time and this feature was viewed by Java developers at best as controversial controversial. Thus .NET designers chose not to include it in C# language.

Fundamentally, whether an exception should be handled or not is a property of the caller, rather than of the function.
For example, in some programs there is no value in handling an IOException (consider ad hoc command-line utilities to perform data crunching; they're never going to be used by a "user", they're specialist tools used by specialist people). In some programs, there is value in handling an IOException at a point "near" to the call (perhaps if you get a FNFE for your config file you'll drop back to some defaults, or look in another location, or something of that nature). In other programs, you want it to bubble up a long way before it's handled (for example you might want it to abort until it reaches the UI, at which point it should alert the user that something has gone wrong.
Each of these cases is dependent on the application, and not the library. And yet, with checked exceptions, it is the library that makes the decision. The Java IO library makes the decision that it will use checked exceptions (which strongly encourage handling that's local to the call) when in some programs a better strategy may be non-local handling, or no handling at all.
This shows the real flaw with checked exceptions in practice, and it's far more fundamental than the superficial (although also important) flaw that too many people will write stupid exception handlers just to make the compiler shut up. The problem I describe is an issue even when experienced, conscientious developers are writing the program.

Interestingly, the guys at Microsoft Research have added checked exceptions to Spec#, their superset of C#.

Anders himself answers that question in this episode of the Software engineering radio podcast

I went from Java to C# because of a job change. At first, I was a little concerned about the difference, but in practice, it hasn't made a difference.
Maybe, it's because I come from C++, which has the exception declaration, but it's not commonly used. I write every single line of code as if it could throw -- always use using around Disposable and think about cleanup I should do in finally.
In retrospect the propagation of the throws declaration in Java didn't really get me anything.
I would like a way to say that a function definitely never throws -- I think that would be more useful.

Additionally to the responses that were written already, not having checked exceptions helps you in many situations a lot. Checked exceptions make generics harder to implement and if you have read the closure proposals you will notice that every single closure proposal has to work around checked exceptions in a rather ugly way.

I sometimes miss checked exceptions in C#/.NET.
I suppose besides Java no other notable platform has them. Maybe the .NET guys just went with the flow...

Related

Should I ever use exceptions in java if I can solve problem without them?

Are exceptions like goto in c don't use it if you don't have to or is it OK to use them as much you want to, and why?
Are they hard on CPU, memory or something else?
You should regard exceptions as a tool that can help you make good software design, similar to data encapsulation (private fields with Getters/Setters), inheritance, interfaces, etc.
The idea of the exception concept in Java is to give you a good way of moving error handling to a spot in your code where it makes most sense. When you face a problem at some line of code, then the first thing you should ask yourself is: Should this method/class that I have here be responsible for handling the problem, or is there a better, more high-level place in my software that should handle it? If you find the latter to be the case, then throwing an exception to that higher-level instance is good design.
Think of it as this: Let's say someone at your work place gives you a pack of bills and tells you to add up the total billing amount. And then in the middle of the bills you find another document that is something completely different. In that case, it would make more sense to go to the person who gave you the pack of documents and let them handle it, instead of deciding for yourself what to do with it, because you may not know what exactly to do.
Example in software: Let's say you have a method that expects a birth date and should calculate the age of the person (difference to current date). But then you find that the given date is incorrect, for instance because it is in future. This method should not deal with fixing the problem, because you might not know how. Is this program a console program and you should print an error, or will it have a GUI? So, you throw an exception to a higher level of the application that knows if there is a GUI or not, and thus whether to print an error to console or show a dialog in the GUI. That's just a simple example, but I hope you get what I mean.
To sum up: Exceptions are nothing "bad" in Java. When used properly, they are a good thing that help you avoid putting responsibilities into objects that they shouldn't have.
...don't use it if you don't have to or is it OK to use them as much you want to...
According to Joshua Bloch's Effective Java:
Exceptions are, as their name implies, to be used only for exceptional
conditions; they should never be used for ordinary control flow.
In order to fully understand this, let's take a look on Java exception. In Java we can find three types of exceptions: checked exceptions, runtime exceptions, and
errors.
Checked exceptions: as their name implies, they should be checked/treated by the developer. Moreover, the compiler forces you to handle this exceptions by try...catch or propagating them upwards by marking the method with throws keyword. These kind of exceptions usually extend the builtin `Exception' class.
Unchecked exceptions: in this group enter both runtime exceptions and errors. The difference between checked exception and unchecked exceptions is that the compiler does not forces you to handle unchecked exceptions. Since they should be used to indicate programming errors, usually it is a good idea to not catch them at all and focus on preventing them. Errors are reserved for use by the JVM to indicate critical failures which usually prevent your program to be recoverable. All of the unchecked
exceptions should subclass RuntimeException class.
So, to give you a response to your first question, it is OK to use exceptions as long as it makes your code readable, more understandable. Moreover, you should be able to deal with exceptions, since compiler will force you to do so. This does not mean that you should throw exceptions whenever you want.
Now let's talk about performance. To repeat myself, exceptions should be used in exceptional cases. This means that they are not as performant as a single if..else would be. Using them wisely, you wont really notice a performance hit, overusing them can cause problems. Exceptions should never be used for control flow (gotos can be used for). In case of memory, every exception creates a new object, which should contain some information about the exception itself. Creating many exceptions would result in occupying more memory, but I don't think that this can be a problem nowadays.
Should I ever use exceptions in java if I can solve problem without
them?
It depends, and is up to you on deciding against or in favor of them. Usually, exceptions are thrown to notify the lack of something (example: no money to withdraw from a credit card, non-existent file to open, etc.) In order to avoid using exceptions in these cases, it is a good idea to return on Optional of something.
This answer is based on Joshua Bloch's Effective Java book. For more information I suggest reading the Exceptions chapter.

How to find a list of possible Java Exceptions

Lets say your program is going to do a variety of math computations and want to know the available exceptions that are possible to capture to see if any are applicable.
Or, the program will be doing a lot of file i/o and other things and you want to capture specific exceptions instead of simply capturing Exception.
Maybe you may want to know if one application is even applicable in the scenario being coded.
What is the recommended way to go about researching what exceptions are available to be captured when generating code to do specific activity?
Using a IDE like Intellij or Eclipse will let you know most of the exceptions that the library code you are using throws, depending on it's javadoc(Like FileNotFoundException) and majority of the times, these are the exceptions that you should worry about.
Other exceptions like divide by zero, null pointer exception will certainly depend on the code you are writing. For example if you getting an object from a different class, you might want to check if it is null before doing any operations on it. Similarly if you are dividing by something, like K/X , you should have an idea whether X is ever going to be 0 or not.
The recomended way is to look into the javadoc of that method.
Hopefully the software author of that code wrote the javadoc in the recomended way, to also list the Runtime Exceptions that a method throws.
You can usually find this information in the Docs for the method you want to use. It will tell you what exceptions it can throw in what cases. There is no general purpose "find all exceptions" technique. This is probably a good things, because if you don't know how or why an exception is created, you probably don't know enough to handle it.
You can trace through the source of the code you are calling to find all the specific exceptions. The problem with this is that the time this takes esp since it could change between different versions of software is very high.
In general you can trust the Javadoc for broad checked exceptions, but this usually won't tell you about all specific exception or all RuntimeExceptions. (Including all future exceptions)
Note: you may wish to take different actions based on the message as well as the type of exception.
For this reason I suggest you focus on the specific exceptions which you handle differently, and have a catch all IOException or similar for unexpected exception which by their nature mean you can't know how to handle them.
There are two types of exceptions, checked and unchecked. If you don't handle checked exception you will get a build failure. You can identify checked exception if you are using any IDE. But unchecked exception are bit tricky and you may need to refer the API documentation to understand what they are, because unless it's thrown you may not know that exception can occur. Again some IDEs give you hints based on your code, for example class casting, null checking.

Is using checked exceptions in external APIs a good idea?

Seeing a checked expection in API is not rare, one of the most well known examples is IOException in Closeable.close(). And often dealing with this exception really annoys me. Even more annoying example was in one of our projects. It consists from several components and each component declares specific checked exception. The problem (in my opinion) is that at design time it was not exactly known what certain exceptions would be. Thus, for instance, component Configurator declared ConfiguratorExeption. When I asked why not just use unchecked exceptions, I was told that we want our app to be robust and not to blow in runtime. But it seams to be a weak argument because:
Most of those exceptions effectively make app unusable. Yes, it doesn't blow up, but it cannot make anything exepting flooding log with messages.
Those exceptions are not specific and virtually mean that 'something bad happened'. How client is supposed to recover?
In fact all recovering consists from logging exception and then swallowing it. This is performed in large try-catch statement.
I think, that this is a recurring pattern. But still checked exceptions are widely used in APIs. What is the reason for this? Are there certain types of APIs that are more appropriate for checked exceptions?
There have been a lot of controversy around this issue.
Take a look at this classic article about that subject http://www.mindview.net/Etc/Discussions/CheckedExceptions
I personally tend to favor the use of Runtime exceptions myself and have started to consider the use of checked exceptions a bad idea in your API.
In fact some very popular Java API's have started to do the same, for instance, Hibernate dropped its use of checked exceptions for Runtime from version 3, the Spring Framework also favor the use of Runtime over checked exceptions.
One of the problems with large libraries is that they do not document all the exceptions that may be thrown, so your code may bomb at any time if an undocumented RuntimeException just happens to be thrown from deep down code you do not "own".
By explicitly declaring all those, at least the developer using said library have the compiler help dealing with them correctly.
There is nothing like doing forensic analysis at 3 in the morning to discover that some situation triggered such an undeclared exception.
Checked Exceptions should only be thrown for things that are 1) Exceptional they are an exception to the rule of success, most poor exception throwing is the terrible habit of defensive coding and 2) Actionable by the client. If something happens that the client of the API can't possibly affect in any way make it a RuntimeException.
There's different views on the matter, but I tend to view things as follows:
a checked exception represents an event which one could reasonably expect to occur under some predictable, exceptional circumstances that are still "within the normal operating conditions of a program/typical caller", and which can typically be dealt with not too far up the call stack;
an unchecked exception represents a condition that we "wouldn't really expect to occur" within the normal running environment of a program, and which can be dealt with fairly high up the call stack (or indeed possibly cause us to shut down the application in the case of a simpler app);
en error represents a condition which, if it occurs, we would generally expect to result in us shutting down the application.
For example, it's quite within the realms of a typical environment that under some exceptional-- but fairly predictable-- conditions, closing a file could cause an I/O error (flushing a buffer to a file on closing when the disk is full). So the decision to let Closable throw a checked IOException is probably reasonable.
On the other hand, there are some examples within the standard Java APIs where the decision is less defensible. I would say that the XML APIs are typically overfussy when it comes to checked exceptions (why is not finding an XML parser something you really expect to happen and deal with in a typical application...?), as is the reflection API (you generally really expect class definitions to be found and not to be able to plough on regardless if they're not...). But many decisions are arguable.
In general, I would agree that exceptions of the "configuration exception" type should probably be unchecked.
Remember if you are calling a method which declares a checked exception but you "really really don't expect it to be thrown and really wouldn't know what to do if it were thrown", then you can programmatically "shrug your shoulders" and re-cast it to a RuntimeException or Error...
You can, in fact, use Exception tunneling so that a generic exception (such as your ConfiguratorException) can give more detail about what went wrong (such as a FileNotFound).
In general I would caution against this however, as this is likely to be a leaky abstraction (no one should care whether your configurator is trying to pull its data from the filesystem, database, across a network or whatever)
If you are using checked exceptions then at least you'll know where and why your abstractions are leaky. IMHO, this is a good thing.

How convince other developers not to ignore Exceptions?

Recently I encountered a bug in an application I took over from another developer. I debugged for the reason and over an hour later I realized, that the problem wasn't the code producing the exception, but some code executed before this returning wrong data. If I dived into this, I encountered the following:
try {
...
} catch (XYException e){}
If the Exception would have been propagated (a change I did), I would have found the reason for the bugs in a few minutes, as the stacktrace had pointed me to the problem. So how can I convince other developers to never catch and ignore exceptions in this way?
Simple rule of thumb: catch exceptions if and only if you have a meaningful way of handling them. Do whatever you need to do at your workplace to propagate this simple rule.
By utilizing tools such as PMD, you can even enforce this in the development environment of all your developers. EmptyCatchBlock (first rule under Basic Rules) is a rule that does exactly what you need. You have some more out-of-the-box rules for exceptions if you need better control on exception handling.
Nevertheless, in my experience, enforcing the use of tools such as PMD is never a substitute to proper development practices and developer education.
Start BadHumour:
Add a silent critical
exception into the code that causes
the application to shut down, and
let them sit and cry trying to find it
for about an hour - Then educate
End BadHumour
The simple rule is simple: Use exceptions for exceptional circumstances. Anything else is silly and wasteful. Compare swallowing of exceptions to eating candy coated razor blades. They may taste nice now, but wait until they start to be digested. (Coding Test system vs. Debugging Live system)
Simple point - have the lead developer declare that. Catching an exception and swallowing it without reason is equal to sabotage and should lead to recursion against the developer (i.e. talk i nHR about his attitude).
As Yuval said, catch exceptions only if you actually do something sensible. let things bubble up if you dont know what or how to handle them. POSSIBLY wrap them in other exceptions IF expected (i.e. a DAL may throw a DataLayerException so that higher up levels can handle all that stuff in one try/catch, but it would not handle something unexpected).
it is a ridiculous way to catch exceptions and swallow them.
The same way you convince other developers to follow any sort of best practice. This particular anti-pattern is a fairly common (and extremely painful!) one, but there's countless other examples of bad coding practices that are probably at least somewhat common among your team members.
In order of difficulty in getting started, here's some recommendations I've seen used effectively in the past:
Talking to the developer, pointing out the problem, and describing how it caused problems for you. The simplest solution - not always effective, and it will only work for that one developer, but it's better than doing nothing.
Public shaming. I've worked in places where we had a "Wall of Shame" with various coding horrors from our project, along with the developer who wrote them. It's really important that this is done in a lighthearted way, and it's really something I wouldn't advise just starting without getting everyone on board, but it's a fun way to point out issues like this.
Reading groups. If you have the means to get a lunchtime reading group started at your office, I highly recommend it. Coding issues like this would be addressed extremely well by a reading group going through "The Pragmatic Programmer".
Code reviews. Again, not the simplest thing to get started if you're not a team lead, but it's absolutely worth a suggestion to yours if you aren't one. If you are a team lead, you should have started code reviews yesterday.
Point them to this link http://www.ibm.com/developerworks/library/j-jtp05254.html an article which explains when to check or uncheck or throw or catch :)
One nice feature I like about the VS.Net debugger is that you can tell it to break when any exception is thrown. It isn't something you would turn on all the time, but can help when you're trying to hunt down a particular bug. I wonder if the same feature exists for Java, since it is an environment very similar to .Net. I think this problem shows up more in Java than it does in .Net however, because Java requires you to handle exceptions, or to at least mark your method as throwing the same exception (AFAIK). So, if you are required to handle it, a lot of bad developers will just swallow it, because they have no idea how to handle it, or what to do with it.
None of this really helps you stop bad developers from doing bad things. I think the best thing you can do, is to do code reviews. Encourage coworkers to look over the list of check-ins to ensure that things are done correctly. With a good source control system, this can be done pretty easily. And human eyes can catch things that computers can't. A computer would be able to delete an empty catch block, but humans can catch a whole lot more antipatterns.
The title does not match the example. In the example the exception is not ignored but handled in a nasty way (this is sometimes referred to as exception swallowing). For this particular malady I recommend static code analysis and bonus/salary reduction.
Charge the time against the developer concerned, or the module concerned, rather than yourself, or your own module.
There are some subtle ways to that (each of those being subjects to discussions)
Make all your application's Exception RuntimeException subclasses. This way, there is no try/catch in your application, and you can easily see (at the thread level) what problème broke the thread. Unfortunatly, this has no effect on the developper that wrote this code block precisely to get rid of an exception he didn't bother to manage.
Use Checkstyle, or an other static code checker, to ensure no empty catch block exists in your application. Unfortunatly, this do not works when no continous integration process exists in your team (since errors notification won't go to the developper responsible for them).
Provide default catch template code with a sensible value (like a logger.log(Level.WARN, "something went wrong here", e)) allowing user to not have to worry about exception management, however having a reasoably good code.

What's the point of an OurCompanyRuntimeException type in Java?

At the company where I am right now, there are a lot of places in the code where an OurCompanyRuntimeException is thrown (where OurCompany is the actual name of the company). As far as I can tell, this exception is described as "A runtime exception thrown by code that we wrote here at this company."
I'm somewhat new to Java, but I thought exception types were supposed to reflect what went wrong, not whose code threw the exception. For example, IllegalArgumentException means someone passed an illegal argument to something. You wouldn't have a SunIllegalArgumentException if an illegal argument was passed in code written by Sun, and then a IBMIllegalArgumentException -- that would be silly and pointless, right? And if you want to know where the exception was thrown, you look at the stack trace. I understand wanting to extend RuntimeException (so that you don't have as many try/catches or "throws"es all over) but why not make subclasses that explain what happened, as opposed to what company's code it happened in?
Has anyone ever used the OurCompanyRuntimeException idea before, or have an idea of why they might have done it this way?
Sounds like the usual bespoke code nonsense that you find in in-house code bases to me. I suspect if you ask about there'll have been some decree that the OurCompanyRuntimeException was used based on some misguided logic by a senior guy that nobody dared question and has long since moved on - the story of the monkeys, bananas and hose-pipes springs to mind.
I agree with you, the name of the exception should be indicative of the error that has occurred.
Helps when reading stack traces, that's for sure. I.e. when scanning through a lot of lines of 'caused by's', it helps to see that it occurred in something thrown by you, not something internal to, say, a container.
Also lets you perform custom actions as part of the throwable - e.g. write to a special log somewhere, etc.
Yes I encountered that, too, but it didn't make sense to me either. My guess was, that the companies wrote this exceptions very early after the adoption of Java without getting the correct idea of how exception throwing and handling really works (like Nick already said... by the senior programmer nobody dared to question).
If the company feels the need to create its own exception class (e.g. for company specific logging porpuses) this exception should never be thrown directly (making it abstract). I would derive concrete Problem describing Exceptions instead or just follow the Spring Framework's idea for Exception handling/throw.
This is a bad concept. Exceptions should be specific for a use case.
Okay, if the company does produce a lot of faulty code/products, they may use that type of exception as advertisement ;)
Your company might be adding code to an already existing project, like an open source code base, and could have just added very little code to it. So in order to trace errors that happen by the company's developers, they thought that they would have their own exception class to distinguish the errors that were there before, from the ones caused by the extension. This way, they can focus only on the ones that are caused by company's developers, and perhaps ask the original source code maintainers to fix the other ones.
With time, when you people have developed a sufficiently large code base through in-house development, you may add more exceptions and remove the CompanynameRuntimeException altogother. Also, they might get more at ease with the level of expertise of the developers, to allow them to treat all errors like one, and not to view the ones caused by company developers more suspiciously.
It would make very good sense to have this as a baseclass for specific exceptions. You thrown a specific exception and catch the base class.
Also it may allow to carry a cause (the REAL exception) plus additional information around. That can be very handy for creating diagnostic output for logging.
Seems pretty silly, logging output or a stack trace will show you who the offending class is, so that explanation doesn't wash. Also seems dangerous, as if people are encouraged to throw the OurCompanyRuntimeException they're throwing RuntimeExceptions, which don't force the caller to handle them and can take down your application.
I agree with you that exceptions should reflect the reason behind them. I've seen a custom exception as the root of a hierarchy, although it probably ought to be abstract, so that you need to create a specific extension to use one, and it definitely shouldn't be a RuntimeException.
It wouldn't be a bad idea to have a generic company wide exception class like you describe that more specific exception cases inherit from. One answer already mentioned the ability specifically catch internal code exceptions and ignore / pass through the ones from core java or third party library code. The key point here is that more specific exceptions should inherit from this one. Throwing a generic company-named exception would be rarely required, and almost never recommended.

Categories