Should exceptions without messages be thrown? - java

Should exceptions without messages ever be thrown? In what cases? For example, when subclassing Exception, should a constructor with no parameters even be given?
public class LexerException extends Exception {
public LexerException(String message) {
super(message);
}
}
or
public class LexerException extends Exception {
public LexerException() {
super();
}
public LexerException(String message) {
super(message);
}
}

Should exceptions without messages ever be thrown? In what cases?
An exception without a message will be thrown any time some code instantiates and throws an exception without a message. Anyone can write code like that.
Of course, if the exception that you are trying to throw does not allow you to instantiate it without a message ... or a with null message ... then you can't. But I've never come across an exception class that insists that the exception is non-null.
One case where exceptions typically have no message is NullPointerException when it is thrown by the JVM itself.
If you are asking should it ... in the sense of whether it is good practice to write code that throws exceptions without a message, the answer is (IMO) No. But you can make up your own mind. (I guess, if the exception name says all that there is to be said, then a message would be redundant. However, it is always useful to have extra information in the stacktrace when debugging.)
Re these comments:
Generally, you should avoid custom exceptions. Use ones that already exist. – mre
Why should I avoid custom exceptions? – Kyranstar
The point is that before you code a custom exception, you should look to see if there is an existing exception that means the same thing as your proposed new one. For example, don't write a custom IllegalLexerArgumentException exception when there is an existing IllegalArgumentException that would serve your purposes.
Why?
For the same reasons that we don't write (say) custom collection classes without good reason. It is a bad idea to write unnecessary code, 'cos that is just more code to compile and test, more space at runtime, more code for the maintainer to read, etc.
Because having lots of exception classes that mean the same thing can make exception handling messy. This effect gets worse as you combine / reuse more libraries to make large applications.

If you don't give the exception any message so you can pop-up the message into anther position when you get the error, but it's recommended to give every exception you create a message and to create an instance of this exception and to throw it.

If the documentation explicitly states there is a single case triggering the exception, then IMHO it is not require to have a message in the exception. Otherwise, it is. A good rule of thumb is: Make it easy for whoever is going to use/debug that code.

Well, honestly I've just searched our code and we use Exceptions without messages, but they are really obvious ones. Like:
UsernameCantBeEmptyException// example only

I think this depends on the use case. The NullPointerException for instance has no message. What could be helpful? No idea. On the other hand there where versions of java where the ClassCastException had no message. That's extremly annoing as the type that should be casted is hart to figure out and is available to the program.
As long as I've no idea for a use case where skipping the message seems appropiate, I'd provide no empty constructor. AFAIK a lexer figures out things like this variable has that type and thus that acion is appropriate or not. This would indicate that the exception message might even have to be presented to he end user. In such a case even localization might be mandatory. If so even some 'factory infrastructre' might be a good idea.
On custom exceptions in general: There's been a tendency to do that to often and then many figured out that in fact no custom exceptions have ever been needed. And in fact there are even hudge programs that need not a single one. On business I work on a 200kLOC program and I don't think we have one. But for sub-systems with specific needs on handling (Like catching all the LexerException to show them in a specific way, separate them from programming bugs in your own code, whatsoever) it might make much sense to have a few. I'm working on a small OSS project and there I have even more than one. But you should always keep in mind that additional exception type must make the exception handling simpler not more complicated. If you often have several catch block one after another, then your definitly on the wrong track. That's a typical symptom of unnecessary custom exceptions.

Related

java - finding out which type of exception to throw

I am confronting with the following issue for some time.
Let's say you have some code and at some point you need to throw an exception. Let's suppose we want to throw a runtime exception.
Java comes with plenty of exceptions and, in some cases, you may find one suitable for your case.
The problem is how can I figure out which of the exceptions is most suitable for my case?
My question is only about the existent Java implementations of RuntimeException and not custom exception which are extending this class.
Let's take an example. I have the following switch statement:
switch(something){
case A: ... break;
case B: ... break;
default: throw new AJavaRuntimeException("No such case defined");
}
What should I use instead of AJavaRuntimeException and comes with Java? How to find the proper exception through Java?
The easiest solution would be to extend RuntimeException and create NoSuchSwitchCaseDefinedException. Or even throw a RuntimeException. But... Maybe Java already has something for this.
Browsing the API for Direct known subclasses of RuntimeException will probably get you your best fit out of the "catalog".
In this case, you could either throw:
IllegalStateException, signalling an illegal state in your program or
IllegalArgumentException, signalling a bad argument
Etc...
If you can't find your exact match, you shouldn't hesitate to extend Exception or RuntimeException depending on your requirements (checked vs not checked).
If you need to throw an exception independently, better throw a custom user defined exception and it has to be checked one.
Never throw runtime exceptions on your own.
Create business exceptions and throw them.
There are many philosophies to follow here. The philosophy I follow is that unchecked exceptions (i.e. everything inheriting from RuntimeException or Error) are solely used to report programming errors (e.g. though an error dialog or a log message). Programming errors should only be handled in a generic way (e.g. by aborting an operation, skipping an optional processing step, etc.). This means that the actual type used for the exception does not matter in a technical sense.
What does matters is that the exception, its name, its message, its accompanying JavaDoc comment make it as simple as possible to identify what triggered the bug, what a possible workaround might be and how to fix the bug in the end.
If you are writing a library that might fail because of incorrect usage, having domain-specific unchecked exceptions might make working with the library more pleasant because you have the opportunity to provide a lot of context and documentation to an error that might otherwise be obscure.
If you are writing an end-user application or service, you or your time are probably one of the only people ever seeing those exception so that extra work might not be worth it and just throwing RuntimeException with a short description of the problem as its message might be enough.

How to avoid creating custom exception classes whilst still throwing exceptions at an appropriate level of abstraction?

I'm reviewing my understanding of exception handling (in the context of Java), and trying to figure out what types of exceptions are most appropriate to throw. One comment that I'm regularly seeing is that it is generally better to avoid creating many custom exceptions - it is better to use the "widely understood" standard exceptions, and only "create a custom exception type when you need to annotate the exception with additional information to aid in the programmatic handling of the symptom."
However, this seems somewhat in contrast to the idea that you should "throw exceptions at the right level of abstraction". Looking at an example from Uncle Bob's 'Clean Code' the following examples are provided for an Employee class:
Bad: public TaxId getTaxId() throws EOFException
Good: public TaxId getTaxId() throws EmployeeDataNotAvailable
So, how do I consolidate these two "recomendations" - that you should only throw exceptions at the right level of abstraction, and you should rarely create custom exception classes. In addition, when searching for information on the standard exceptions in Java, there is very very little well presented and formatted information on what standard exception classes are available - I'm looking for standard exceptions that would semantically still seem to be appropriate for calling classes, but not finding much to go on. Of course you can find the what exception classes are available in the jdk documentation, but just the general lack of info and discussion online seems strange.
So, this is where I'm at right now. Any suggestions and comments are much appreciated!
The level of abstraction is judged to be right or wrong by the user of your code. To justify an existence of AExeption and BException there should be a use-case where the user differentiates between them, e.g:
} catch(AExeption ae) {
// do something
} catch(BException be) {
// do something different
}
as opposed to always:
} catch(AExeption ae | BException be ) {
// do something
}
My experience is that real world systems tend to go easy on the amount of logic that goes into the programmatic handling of the symptom
I don't think there's an specific answer for your question. In my projects, I tend to follow these guidelines for custom exception classes:
If I can encounter with an exception in a method, check if the exception can be described by any of the subclasses of Exception or, if possible, a subclass of RuntimeException. The javadocs provide enough info about the basic classes that extend from both Exception and RuntimeException and each exception class could also have more subclasses that weren't listed before e.g. IOException.
If there's no subclass of Exception or RuntimeException or any, create a custom exception class or reuse one previously created but with a distinct message. Usually, I tend to create these classes extending from RuntimeException to avoid clients of the method using try-catch blocks. If there's the need to handle the exception in the client of this method, then it should extend from Exception.
The custom exception classes are associated to a process or specific event in the application.
If developing a business application, then the name of the exception can be related to the business process you're working with. For example, if I'm developing a process that creates a bill from a set of input data (e.g. products, services, customer data, etc), then I would provide at least 2 custom exception classes:
ElementNotFoundException, probably for not finding a specific kind of input e.g. missing product or Customer#billingAddressLocation is null due to a wrong migration of the data of some customer.
BillGenerationException, generated when there's a problem after collecting the necessary data to generate the bill and in the exact process of generate the bill.
It's quite philosophical question.
But in general it means that you should create your own exception with considering of existing ones.
Example :
In case of usage some external service and this service is unavailable
, in this case I wouldn't recommend you to throw your own exception,
because "Connection Refused" or "Connection timed out" will understand
on the spot every programmer after you, for checking your custom
exception programmer will need to go to source code and spend some
time to understand your exception after noticing it in production
logs.
But if I see that my wrapper will be clearer for such case I am adding my wrapper.
There is no contradiction between using exceptions of the right level of abstraction and refraining from creating new exception classes. What you must do is choose the most appropriate existing exception class for the particular method you are interested in if you can.
So if the clear meaning of a getTaxiId method does not suggest the method performs I/O, declaring it to throw an IOException of any kind would be inappropriate. You would then have to search the other existing exception classes for a more approriate exception class. If you did not find such a class, you know it is appropriate to create a new exception class.
I think Uncle Bob is looking at the problem from the wrong end.
You throw an exception to unravel the call chain and inform a non-local piece of logic that something unexpected and detrimental happened and allow it to respond.
I can understand wrapping an EOFException and all sorts of bad data problems into some generic InvalidDataException but providing a specific EmployeeDataException seems like overkill.
It may be useful for the calling process to (say) know that there was a local data exception and not, for example, a lost connection. That way it could abandon a unit of work but realistically continue trying to process the next one.
So, do throw at an appropriate level of abstraction - for the catcher to respond usefully.
If you think about it, if you create a different exception for each object type, someone will have to maintain catchers for all object types in play!
Tomorrow a new exception called AddressDataException is introduced and various (obscure) catcher chains need that added as yet-another-data-exception category.
Of course the answer is to introduce a DataException category as super-class to all those specialised ones.
But as soon as you do that you'll change all the handlers to catch the generic exception and realise that the correct level of abstraction is a generic DataException because that's what is useful to the catcher.

Why should we write custom exception classes in Java

What is the purpose of writing custom exception classes when mostly what it does is same.
For eg, NullPointerException:
class NullPointerException extends RuntimeException {
private static final long serialVersionUID = 5162710183389028792L;
public NullPointerException() {
super();
}
public NullPointerException(String s) {
super(s);
}
}
This is the basic template for most exception classes that I have seen and created.
One purpose I can think of is in handling these exception.But then cant this be based on Exception Message?. Mostly we write single handling code for each exception type. I know there are 'exceptions' to this.
But is there anything more to it? Isnt this repeating yourself where only the class name changes?
Also are there any JDK Exception classes that has some code than this?
I can think of several reasons:
Having multiple exception classes allows the programmer to be specific in their catch clauses, and only catch the exceptions they care about and know what to do with.
An exception class can carry information about the error that's caused the exception. For example, ArrayIndexOutOfBoundsException carries the offending array index, and SQL exceptions tends to carry database-specific error codes and messages.
Exception specifications -- that list exception classes -- can be used to check correctness at compile time.
Well, simply put, if you do not need special exception class, you should not make one. If you do, then you make one. There's no magic to it really.
If you're making a library, then you should of course think from the point of view of the developers using the library (even if it is just you): does your library throw exceptions for specific reasons and could the library user possibly want to catch specifically these, because they can realistically do something about it (just logging isn't reason enough, IMO).
Example with standard exception classes: Caller of a method might want to convert IndexOutOfBoundsException to null return value, while letting other exceptions to propagate normally.
If you want your custom exception to be handled in default ways, you extend right existing exception class, such as IOException. You can then catch your specific IO exception when you want to do something specific just there, but also let it be handled like any other IOException when you don't need special handling (can't do anything useful to recover).
If you have a totally custom exception which should never be caught by a superclass catch, which always should have specific catch block, then you extend Exception directly.
I think it's pretty rare to need to extend RuntimeException, because if it an exception meant to be caught it should be Exception subclass, and if it's meant to end the program or just generate log output, then it should be covered by default RuntimeException implementations with custom message string.
You need to have your client code know what exact exception happens by which part of code. so you need to let exception semantic and distinguished from other code block.
How to do this:
Define new exception class, so the class name tells what happens
Define a unifed/generic exception class which wraps code, message or other info. the code can tells what happens.
To summarize it, Do something let your exception have some meaning/semantics, and let its client know what exactly happens.
We will have a freedom to add few more methods into our Exception class which helps the client like rootCauseOfException(),description(),solution(),suggestions() etc.
Can refer below link:
https://stackoverflow.com/a/22698673
If your project has interdependent modules then you can maintain exception hierarchy also in the same dependency hierarchy so that if you catch single Exception in base layer then all the interdependent modules exceptions will be caught.
You can also mask some sensitive data like ip ,port etc before sending to client side. If custom exceptions are not used then some sensitive data can may get leaked to slient.
You can provide your own exception message which can be easily understandable by client rather than java's exception message sometimes which may be hard to understand .
It is basically to Handle different Exception in different ways. Say, you might want to do some different operation on ArrayIndexOutOfBoundsException than a NumberFormatException.
or more clearly
}catch (ArrayIndexOutOfBoundsException ex){
//operation 1
}catch (NumberFormatException ex){
//operation 2
}
The main purpose would be identify the custom / app-specific errors. You can also provide some additional methods there. For eg, we have custom exceptions that return custom messages, and also extracts cause and location from the stack trace.

Is there an advantage to wrapping exceptions with Custom exception types in Java

I have a class XYZ whose public functions throw Exceptions.
I have been advised that all public functions exposed by XYZ should throw exceptions called XYZDataException or XYZSystemException. So even if I get other exceptions within the public methods they need to be wrapped by these XYZExceptions.
I have a couple of questions:
What is the advantage of wrapping exceptions with XYZException?
What is the advantage of differentiating between System and Data exceptions?
To me it feels right to just throw whatever exception occurs without wrapping it further.
A lot of Exception handling depends on how you plan on extending it later on. For example, if developer B came along and wanted to modify some of your code, it would be a lot easier if he understand what Exception meant what in which case. In that case, having specific Exceptions makes more sense.
As to breaking up System and Data exceptions - a Data exception would basically be something that should be non-fatal that occurs because of bad data. A System exception would be because your System failed in some way. Again, this all points to how you want to use it later on. If you want to use your code solely, and you don't care about how your exceptions come back out, then by all means, go with what is easiest at the time.
I have found that when working with other developers on a project, it is a lot easier for them to grasp what is going on when you subclass your Exceptions and throw them in specific cases.
Hope this helps!
Yes, it means they can be explicitly caught by code that knows how to handle them.
for instance, imagine you had:
class MyRecoverableException extends Exception {
...
}
You could then have code that can differentiate between them automatically, and react accordingly, such as:
try{
// ... do something ...
}catch(MyRecoverableException e) {
// Recover
}catch(Throwable t) {
// Log fatal reason, and exit gracefully.
}
Obviously how many you need is a problem to be solved by you, the application developer, but a clean separation can make all the difference when working out what went wrong, and subclassed exceptions can hold additional properties, used to pass pertinent information to handlers about the exceptional circumstances that brought them about.
Having a base type to extend from for your application/library never hurts either - if for no other reason than to allow separation of source when logging - but the exact hierarchy and complexity required beyond that depends entirely on the project. Some designs have natural and obvious choices, some require a bit more forethought (and occasionally a bit of afterthought and refactoring).
As usual, "it depends". As a general rule it does not make sense to blindly create an exception hierarchy on a per-class basis. App-specific exceptions should group exceptions in a way meaningful to that particular app, so there might be a top-level exception, then sub-classed exceptions for things like the data layer, communication layer, utilities, whatever.
The advantage is that higher levels dealing with those exceptions are not exposed to the implementation details that generate those exceptions. Also, perhaps to a lessor degree, exceptions may be grouped more meaningfully (is it relevant that it was an IOException, or is it enough to know there was a problem writing to whatever output store you're using).
Another great advantage is that app-specific information may be captured in the custom exceptions. Things like user IDs, account numbers, etc.--any application state--which must be stored as part of a string message in a "stock" exception may be assigned to a property. This may avoid random parsing issues if you actually do anything with the exceptions or try to trace through a particular event stream.
According to msdn:
To wrap an exception, you specify it as the inner exception of a new exception and then throw the new exception. This practice should be used only in situations where the original exception is not meaningful to the person who receives the exception, or the call stack for the exception is misleading or uninteresting.
Suppose method M1 is documented as throwing an exception of type X when some condition occurs. M1 calls method M2, which happens to throw an exception of type X which M1 is not prepared to handle. If M1 doesn't catch the exception from M2, the caller is unlikely to figure out that the exception thrown out of M1 isn't an X thrown by M1, but is instead an X thrown by M2, and its practical meaning and implications may be very different. Having M1 throw an exception of a type which will never be thrown by M2 may avoid this issue (though there could still be trouble if M2 could call M1 on some other object).

In Java, when should I create a checked exception, and when should it be a runtime exception? [duplicate]

This question already has answers here:
Closed 10 years ago.
The community reviewed whether to reopen this question last year and left it closed:
Original close reason(s) were not resolved
Possible Duplicate:
When to choose checked and unchecked exceptions
When should I create a checked exception, and when should I make a runtime exception?
For example, suppose I created the following class:
public class Account {
private float balance;
/* ... constructor, getter, and other fields and methods */
public void transferTo(Account other, float amount) {
if (amount > balance)
throw new NotEnoughBalanceException();
/* ... */
}
}
How should I create my NotEnoughBalanceException? Should it extend Exception or RuntimeException? Or should I just use IllegalArgumentException instead?
There's a LOT of disagreement on this topic. At my last job, we ran into some real issues with Runtime exceptions being forgotten until they showed up in production (on agedwards.com), so we resolved to use checked exceptions exclusively.
At my current job, I find that there are many who are for Runtime exceptions in many or all cases.
Here's what I think: Using CheckedExceptions, I am forced at compile time to at least acknowledge the exception in the caller. With Runtime exceptions, I am not forced to by the compiler, but can write a unit test that makes me deal with it. Since I still believe that the earlier a bug is caught the cheaper it is to fix it, I prefer CheckedExceptions for this reason.
From a philosophical point of view, a method call is a contract to some degree between the caller and the called. Since the compiler enforces the types of parameters that are passed in, it seems symmetrical to let it enforce the types on the way out. That is, return values or exceptions.
My experience tells me that I get higher quality, that is, code that JUST WORKS, when I'm using checked exceptions. Checked exceptions may clutter code, but there are techniques to deal with this. I like to translate exceptions when passing a layer boundary. For example, if I'm passing up from my persistence layer, I would like to convert an SQL exception to a persistence exception, since the next layer up shouldn't care that I'm persisting to a SQL database, but will want to know if something could not be persisted. Another technique I use is to create a simple hierarchy of exceptions. This lets me write cleaner code one layer up, since I can catch the superclass, and only deal with the individual subclasses when it really matters.
In general, I think the advice by Joshua Bloch in Effective Java best summarises the answer to your question: Use checked expections for recoverable conditions and runtime exceptions for programming errors (Item 58 in 2nd edition).
So in this case, if you really want to use exceptions, it should be a checked one. (Unless the documentation of transferTo() made it very clear that the method must not be called without checking for sufficient balance first by using some other Account method - but this would seem a bit awkward.)
But also note Items 59: Avoid unnecessary use of checked exceptions and 57: Use exceptions only for exceptional conditions. As others have pointed out, this case may not warrant an exception at all. Consider returning false (or perhaps a status object with details about what happened) if there is not enough credit.
When to use checked exceptions? Honestly? In my humble opinion... never. I think it's been about 6 years since I last created a checked exception.
You can't force someone to deal with an error. Arguably it makes code worse not better. I can't tell you the number of times I've come across code like this:
try {
...
} catch (IOException e) {
// do nothing
}
Whereas I have countless times written code like this:
try {
...
} catch (IOException e) {
throw new RuntimeExceptione(e);
}
Why? Because a condition (not necessarily IOException; that's just an example) wasn't recoverable but was forced down my throat anyway and I am often forced to make the choice between doing the above and polluting my API just to propagate a checked exception all the way to the top where it's (rightlfully) fatal and will be logged.
There's a reason Spring's DAO helper classes translate the checked SQLException into the unchecked DataAccessException.
If you have things like lack of write permissions to a disk, lack of disk space or other fatal conditions you want to be making as much noise as possible and the way to do this is with... unchecked exceptions (or even Errors).
Additionally, checked exceptions break encapsulation.
This idea that checked exceptions should be used for "recoverable" errors is really pie-in-the-sky wishful thinking.
Checked exceptions in Java were an experiment... a failed experiment. We should just cut our losses, admit we made a mistake and move on. IMHO .Net got it right by only having unchecked exceptions. Then again it had the second-adopter advantage of learning from Java's mistakes.
IMHO, it shouldn't be an exception at all. An exception, in my mind, should be used when exceptional things happen, and not as flow controls.
In your case, it isn't at all an exceptional status that someone tries to transfer more money than the balance allows. I figure these things happen very often in the real world. So you should program against these situations. An exception might be that your if-statement evaluates the balance good, but when the money is actually being subtracted from the account, the balance isn't good anymore, for some strange reason.
An exception might be that, just before calling transferTo(), you checked that the line was open to the bank. But inside the transferTo(), the code notices that the line isn't open any more, although, by all logic, it should be. THAT is an exception. If the line can't be opened, that's not an exception, that's a plausible situation.
IMHO recap: Exceptions == weird black magic.
being-constructive-edit:
So, not to be all too contradictive, the method itself might very well throw an exception. But the use of the method should be controlled: You first check the balance (outside of the transferTo() method), and if the balance is good, only then call transferTo(). If transferTo() notices that the balance, for some odd reason, isn't good anymore, you throw the exception, which you diligently catch.
In that case, you have all your ducks in a row, and know that there's nothing more you can do (because what was true became false, as if by itself), other than log the exception, send a notification to someone, and tell the customer politely that someone didn't sacrifice their virgins properly during the last full moon, and the problem will be fixed at the first possible moment.
less-enterprisey-suggestion-edit:
If you are doing this for your own pleasure (and the case seems to be this, see comments), I'd suggest returning a boolean instead. The usage would be something like this:
// ...
boolean success = transferTo(otherAccount, ONE_MILLION_DOLLARS_EXCLAMATION);
if (!success) {
UI.showMessage("Aww shucks. You're not that rich");
return; // or something...
} else {
profit();
}
// ...
My rule is
if statements for business logic errors (like your code)
cheched exceptions for environment errors where the application can recover
uncheched exception for environment errors where there is no recovery
Example for checked exception: Network is down for an application that can work offline
Example for uncheched exception: Database is down on a CRUD web application.
There is much documentation on the subject. You can find a lot by browsing the Hibernate
web pages since they changed all exceptions of Hibernate 2.x from checked to unchecked in version 3.x
I recently had a problem with exceptions, code threw NullPointerException and I had no idea why, after some investigation it turned out that real exception was swallowed(it was in new code, so its still being done) and method just returned null. If you do checked exceptions you must understand that bad programmers will just try catch it and ignore exception.
My feeling is that the checked exception is a useful contract that should be used sparingly. The classic example of where I think a checked exception is a good idea is an InterruptedException. My feeling is that I do want to be able to stop a thread / process when I want it to stop, regardless of how long someone has specified to Thread.sleep().
So, trying to answer your specific question, is this something that you absolutely want to make sure that everyone deals with? To my mind, a situation where an Account doesn't have enough money is a serious enough problem that you have to deal with it.
In response to Peter's comment: here's an example using InterruptedException as concrete case of an exception that should be handled and you need to have a useful default handler. Here is what I strongly recommend, certainly at my real job. You should at least do this:
catch (InterruptedException ie) {
Thread.currentThread().interrupt();
}
That handler will ensure that the code catches the checked exception and does exactly what you want: get this thread to stop. Admittedly, if there's another exception handler / eater upstream, it's not impossible that it will handle the exception less well. Even so, FindBugs can help you find those.
Now, reality sets in: you can't necessarily force everyone who writes an exception handler for your checked exception to handle it well. That said, at least you'll be able to "Find Usages" and know where it is used and give some advice.
Short form: you're inflicting a load the users of your method if you use a checked exception. Make sure that there's a good reason for it, recommend a correct handling method and document all this extensively.
From Unchecked Exceptions -- The Controversy:
If a client can reasonably be expected
to recover from an exception, make it
a checked exception. If a client
cannot do anything to recover from the
exception, make it an unchecked
exception.
Note that an unchecked exception is one derived from RuntimeException and a checked exception is one derived from Exception.
Why throw a RuntimeException if a client cannot do anything to recover from the exception? The article explains:
Runtime exceptions represent problems
that are the result of a programming
problem, and as such, the API client
code cannot reasonably be expected to
recover from them or to handle them in
any way. Such problems include
arithmetic exceptions, such as
dividing by zero; pointer exceptions,
such as trying to access an object
through a null reference; and indexing
exceptions, such as attempting to
access an array element through an
index that is too large or too small.
A checked exception means that clients of your class are forced to deal with it by the compiler. Their code cannot compile unless they add a try/catch block.
The designers of C# have decided that unchecked exceptions are preferred.
Or you can follow the C-style and check return values and not throw exceptions.
Exceptions do have a cost, so they shouldn't be used for control flow, as noted earlier. But the one thing they have going for them is that they can't be ignored.
If you decide that in this case to eschew exceptions, you run the risk that a client of your class will ignore the return value or fail to check the balance before trying to transfer.
I'd recommend an unchecked exception, and I'd give it a descriptive name like InsufficientFundsException to make it quite clear what was going on.
Simply put, use checked exception only as part of external contract for a library, and only if the client wants/needs to catch it. Remember, when using checked exception you are forcing yourself on the caller. With runtime exception, if they are well-documented, you are giving the caller a choice.
It is a known problem that checked exceptions are over-used in Java, but it doesn't mean that they are all bad. That's why it is such in integral part of the Spring philosophy, for example (http://www.springsource.org/about)
The advantage of checked exceptions is that the compiler forces the developer to deal with them earlier. The disadvantage, in my mind anyway, is that developers tend to be lazy and impatient, and stub out the exception-handling code with the intention of coming back and fixing it later. Which, of course, rarely happens.
Bruce Eckel, author of Thinking in Java, has a nice essay on this topic.
I don't think the scenario (insufficient funds) warrants throwing an Exception --- it's simply not exceptional enough, and should be handled by the normal control flow of the program. However, if I really had to throw an exception, I would choose a checked exception, by extending Exception, not RuntimeException which is unchecked. This forces me to handle the exception explicitly (I need to declare it to be thrown, or catch it somewhere).
IllegalArgumentException is a subclass of RuntimeException, which makes it an unchecked exception. I would only consider throwing this if the caller has some convenient way of determining whether or not the method arguments are legal. In your particular code, it's not clear if the caller has access to balance, or whether the whole "check balance and transfer funds" is an atomic operation (if it isn't then the caller really has no convenient way of validating the arguments).
EDIT: Clarified my position on throwing IllegalArgumentException.
Line is not always clear, but for me usually RuntimeException = programming errors, checked exceptions = external errors. This is very rough categorization though. Like others say, checked exceptions force you to handle, or at least think for a very tiny fraction of time, about it.
Myself, I prefer using checked exceptions as I can.
If you are an API Developer (back-end developer), use checked exceptions, otherwise, use Runtime exceptions.
Also note that, using Runtime exceptions in some situations is to be considered a big mistake, for example if you are to throw runtime exceptions from your session beans (see : http://m-hewedy.blogspot.com/2010/01/avoid-throwing-runtimeexception-from.html for more info about the problem from using Runtime excpetions in session beans).

Categories