Is there any case when NPE and IAE get handled differently? [closed] - java

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
Concerning the holy war question about choosing the proper exception in case of a null argument, I wonder if this choice has any practical consequences. I mean, is there a case when you'd catch a NullPointerException and not IllegalArgumentException, or vice versa, or catch both and handle them differently?
To make it clear: This is definitely not the linked question. I'm not asking what exception to throw... I'm asking if they ever get handled differently. I know that with both being RuntimeExceptions they hardly ever get caught, but sometimes you have to do it.

The intent of both exceptions is quiet different
NPE - in most scenarios that I can think of it occurs due to programming errors, so should not be handled.
In case of null, NPE should be thrown in a fail fast manner as it affects the trace. For which I personally use Preconditions.checkNotNull(E ref, String message) of Guava.
IAE - This means there that the class did not expect such a value from the caller. There can be scenarios when you can catch that exception and use default value for recovering.
I know that with both being RuntimeExceptions they hardly ever get
caught
According to me this is quite a misconception that Runtime exceptions are hardly ever caught. Nowadays APIs are depending more on Runtime exceptions as they want to leave on the caller to decide whether the exception gets caught. Many APIs impose you to catch many exceptions which leads to a lot of pain when you know that exception is never going to occur. You are forced to catch it and leave an empty catch block or better log that it should not occur.
The APIs do however specifically document when a particular exception is meant to occur.
Take an example of Integer.parseInt(String s) which throws NumberFormatException and which is a Runtime exception, in most scenarios when I have used it I always catch it and do some recovery using default values.
Think of the scenario if NumberFormatException would have been a checked exception, and you making a call Integer.parseInt("1"), it is clearly visible that it won't occur but still you will be forced to catch it. Agreed that the example is a hypothetical one, but gets my point through.
Again this is just my opinion based on my experience.
I'm asking if they ever get handled differently.
As I have wrote NPE is not caught in most scenarios, but there are always exceptions. Like suppose there is a part of your system that is kept open for extension for someone else to program and there is NPE in that code and you don't want the upper layers to be affected by it then I catch NPE and remove that component from the system giving proper logs and traces. A concrete example is a pluggable system, I didn't want my whole system to crash due to programming error in a user written plugin. So I caught Exception. This may be a bad example for others but worked for me.

IllegalArgumentException can be caught when sanitizing a user input based on criteria known only in the throwing method. It is a more subjective notion, and therefore I sometime catch it.
null you can always test yourself.

I don't think there is any difference from a technical point of view. I'd say stick to a strategy and document it as best as you can. Moreover, these are runtime exceptions, so they are not meant to be caught as they should happen in case of bugs or when a client calls a method/service without providing all the required parameters. Let it crash!
About the holy war question, I do believe NPE should only happen when a client tries to access a variable they think is not null but is, indeed, null and thus never thrown directly. IAE is more appropriate if a client expects a non null value and receives a null from a caller. This is IMO, don't want to take part in the feud.

Related

Should I throw checked or unchecked exception for invalid input? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I'm writing a method which expect some input. Now, I thought that it would be a good practice to write it in a defensive way (i.e. checking that the input is correct).
Basically, the input should be okay since there's only one place (reliable) that uses this method.
So my question is,
Is the defensive programming justified here?
If so, should it throw a checked or unchecked exception?
Multiplying in an idiomatic way the same input checks in each layer of the call is generally a bad practice : you repeat yourself and changes for it can fast become an hell or a messy.
So I would think that if your method is designed to be an API usable by multiple client classes it should do this check even it may be redundant. Otherwise just stay DRY.
Note that the best way to ensure consistency in your API is covering your methods by unit tests.
In this way you provide the checks only when its functional requirement demands that and you don't overthink.
If so, should it throw a checked or unchecked exception?
Using checked or unchecked exceptions usage is very debatable.
In theory checked exceptions are great when it is required that the client handles it. But in practice it may become noise if the client don't want to handle it or if the method is used inside a lambda body.
Think about what will happen to the rest of the system or application if you did not have that check and some invalid input came in.
Do you have a safe default value to fallback and use? Is it the correct value for all cases? Does the caller/client of your code/API need to be notified of this?
So, based on this, you can even just log a warning and can continue using the default value. But in most cases, it will not be the case.
[..] there's only one place (reliable) that uses this method.
It is as of today. In the future, it might change. So, IMO, you can have the check that the input is valid.
should it throw a checked or unchecked exception?
That again takes us back to the callers or clients of your code/API. Do you want them to expect it to happen and handle it?
If they can handle the exception and recover, then it makes sense (Note: This means that all the callers need to have a try..catch block when calling your API/code). Else, if they are supposed to pass a valid value and if they don't, an unchecked exception will do (Make this clear in the contract/Javadoc)
Let us look at an example in the Java libraries itself.
Many methods in the File class throw a checked exception.
Integer.valueOf throws an NumberFormatException (which is an unchecked expcetion) if the input is invalid.
A good practice is, any public API must validate its inputs.
Also, have a look at Java: checked vs unchecked exception explanation
before deciding
Basically, the input should be okay since there's only one place
(reliable) that uses this method.
It's great, that you reason about your function this way. You just defined a contract for your function. It says, that this function expects a valid input. In this case, it is a very good practice to employ defensive programming by throwing an exception when invalid input is detected. This exception will greatly simplify detection of callers of your function, who broke contract and called your function with invalid input.
If you did not throw a dedicated exception, than (if you are lucky) your function might break by throwing a generic technical exception, e.g. NullPointerException or perhaps ArrayIndexOutOfBoundsException. Such stacktrace still shows, that something wrong happened, when your function was called. However, you need to analyze, "what" happened. In worst case, your function would not throw any exception at all and "somehow" process invalid input. Your program than can later break on seemingly unrelated location or in even worse case, it does not break and it presents wrong result to the user.
Is the defensive programming justified here?
Yes, it definitely is.
If so, should it throw a checked or unchecked exception?
Checked vs unchecked exceptions is still an ongoing debate. You can find many answers to this question on StackOverflow. Scala language only has unchecked exceptions. I personally prefer them too.
What if your function expects invalid input too?
Typically, these are functions, which receive input from humans. For example an user registration form requires password, which is not too short and contains at least one digit. In this case, "failure" is expected and should somehow be encoded in function's return value, so that caller of the function is forced to inspect both kinds of return value - Success and Failure. Such return values can be modeled using algebraic data types. Java does not allow to model ADTs naturally and we got used to model Failure by throwing an exception. Maybe in this case checked exceptions still make sense.
Edit:: Other answers go into more details on "when" to validate and when to not. To summarize: public methods - yes; do not repeat same validation across layers.
I didn't take your whole question into account, so I will change my answer.
Should you check input?
With public methods - Always. Reason being that best practice is always to call interfaces and not implementations. So when you have an interface, you want anyone using your implementation of it, to get proper feedback if they pass invalid arguments.
Should you throw exceptions?
Yes! As Uncle Bob says it's better to forget to catch an exception than forget to check a return value to check for errors. In other words, exceptions are more fool proof as they don't fail "silently".

Runtime exception and Checked exception [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
There are so many exceptions, and it is not easy to remember. Is there any rule to know which kinds of exception will fall in which type (runtime vs checked), so that we know in which case we need to catch and in which case we just throw an exception? Thanks!
First of all, no exceptions are compile-time exceptions. The differentiation is checked exceptions vs. unchecked exceptions. The differentiation is made by the compiler by behaving as if each and every operation (method, constructor and initializer block) signature always implicitly includes throws Error, RuntimeException in its declaration. This way, the handle-or-declare rule, which means the compiler forces you to either handle an exception in a catch clause or declare an exception with a throws declaration is disabled for Error and RuntimeException - they are always implicitly declared.
So we overall have the following categories:
Compiler-treatment:
unchecked exception (handling is optional): RuntimeException and Error
checked exception (handle-or-declare rule applies): All other exceptions, including Throwable.
Categories:
Error - we usually do not catch these.
RuntimeException - catching depends on root cause.
Exception - we must handle or declare them (compiler enforces).
Error is easy to remember. If the VM or one of its APIs thinks it's a defect of the VM or the API that causes the issue, it's an Error. Usually we do not catch Errors, although there are a few prominent examples, like these:
catching OutOfMemoryError in resource allocating code to let the application continue after displaying an error message to the user. I.e. the user wants to load an image that's too big.
catching AssertionError in Unit Test frameworks. (They actually catch Throwable, but AssertionError is treated specially, it's a test failure, not a test error.)
Runtime exceptions are exceptions which do not happen if the program was written correctly, as long as the conditions that could lead to these exceptions do not depend on the user. For example, Integer.parseInt(String) throws NumberFormatException. If the String that is converted is coming from the program itself, it should be correct and we wouldn't care about the exception. If the String that is converted is coming from the user, we would usually rather catch NumberFormatException than letting the user crash the program by means of faulty input.
Other exceptions are used where the fault condition is somewhat likely but the program is always expected to handle them in some way. For example, if you open a file, it could always be that the file doesn't exist, cannot be read due to lack of permissions or locking, or that the storage is corrupt.
If you want to be new about things just catch everything... (horrible idea though only for the lazy) Otherwise look at the javados and it will tell you what is throw with each method.
try {
// this code
} catch (Exception e) {
e.printStackTrace();
}
Yeah if you have an issue at compile it means it just doesn't compile therefore doesn't exist and cannot run.
Do not catch RuntimeExceptions and Errors, catch other exceptions or add throws to method declaration

Why is catching a RuntimeException not considered a good programming practice? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Why is catching a RuntimeException using catch(Throwable exc) {} not considered a good programming practice? What is the right way to handle RuntimeExceptions?
Also, why does catch(Exception exc) {} not catch RuntimeException? How is this behavior implemented?
Usually, a RuntimeException indicates a programming error (in which case you can't "handle" it, because if you knew to expect it you'd have avoided the error).
Catching any of these general exceptions (including Throwable) is a bad idea because it means you're claiming that you understand every situation which can go wrong, and you can continue on despite that. It's sometimes appropriate to catch Exception (but not usually Throwable) at the top level of the stack, e.g. in a web server - because usually whatever's gone wrong with a single request, you normally want to keep the server up and responding to further requests. I don't normally catch Throwable, as that includes Error subclasses which are normally used to indicate truly catastrophic errors which would usually be best "handled" by terminating the process.
Fundamentally, when there's an error you need to be very cautious about continuing with a particular task - you need to really have a pretty good idea about what the error means, as otherwise you could go ahead with a mistaken assumption about the state of the world, and make things worse. In most cases (not all), simply giving up on a request is better than trying to carry on regardless of a mysterious failure. (It does very much depend on context though - you might not care what went wrong when trying to fetch one piece of secondary information, for example.)
As for catching Exception not catching RuntimeException - that's simply not true. The only odd thing about RuntimeException is that it (and subclasses) are unchecked exceptions, whereas Exception and all other subclasses of Exception are checked.
It boils down to the different types of exceptions there actually are.
Checked exceptions (that is, exception classes that extend Exception) are typically errors you can recover from.
Unchecked exceptions (that is, exception classes that explicitly extend RuntimeException) are those that indicate an error in either expected behavior or program state. You wouldn't get a NullPointerException if the state of an object wasn't null when you dereferenced it, of course.
Blanket-catching everything - either Exception or Throwable, which is far worse - is not a good practice because you're assuming that you can recover from any exceptional behavior. There are some cases in which you shouldn't, or realistically can't (i.e. OutOfMemoryError for catch(Throwable t)). Further, catching runtime exceptions indicates a code smell; it means that you're covering up a coding error.
Be explicit about what it is you're catching.
Aside: Yes, catch Exception will also catch RuntimeException, since Exception is a superclass of RuntimeException. Just the same, Throwable will catch Exception and Error, which is why it's worse to write catch(Throwable t).
Throwable is super class of all Exception checked and unchecked(RuntimeException) and error.
java.lang.Object
java.lang.Throwable
java.lang.Exception
java.lang.RuntimeException
java.lang.Error
Ideally catching error is not a good practice.
And as RuntimeException extends Exception so it catches all RuntimeExcption's.

Should IndexOutOfBoundsException be checked? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I recently tracked down a bug where a list was of length 0 but an access attempt was made at position 1
System.out.println("key is " + keyValuesPairs.get(0)+ " , value is " + keyValuesPairs.get(1));
This caused an IndexOutOfBoundsException but because it was not caught the exception is silently dropped and no indication is made that an exception is thrown. For this reason should IndexOutOfBoundsException be a checked exception as it can cause difficult to find bugs ?
Update : the exception is not silently dropped.
Your problem is not Should I catch this exception? it is Why is this exception being consumed unreported?.
There is indeed a fault in the code but the other fault - the hidden one that is quietly consuming your exception and discarding it - is a much more pernicious error.
This is why
...
} catch (Exception e) {
// Ignore it.
}
is almost always a code smell.
No I shouldn't be catched. It's a runtime exception see this link for more details : http://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html
What you can do is testing on the index you are using against the array length
I would not catch that exception. Instead I would simply check the bounds like this:
if(keyValuesPairs.size() > 0) {...}
You already answered the question:
"I recently tracked down a bug where a list was of length 0 but an access attempt was made at position 1."
It is a bug in the code - you need to resolve the issue where it's even possible for an index larger than array can be used. There's a reason this isn't a checked exception (meaning Java does not require you to catch it). And that reason is you cannot possibly know why an incorrect index was used when the error occurs, and cannot gracefully recover from it.
You should fix the bug you found and not catch the exception. Make it so the exception no longer is thrown.
All RuntimeExceptions are things that ideally, should never need to happen. They are caused when a program is not sufficiently careful with regard to the unknown, and tries to do things that no sane method should ever consider, and with objects and methods they have only the shallowest glimpse of.
Sometimes, a method is unwittingly tricked into attempting something it shouldn't, by a nefarious master who forces them to take a null or empty array, even though the method's documentation indicate it is unqualified to handle such things. But worse still, when the master gets word that their schemes failed, some will try to cover up their failure, by intercepting the exception before it can reach its superiors, corrupting the system with laziness and sloppiness. Even when the master has a suitable way to deal with their failure, they still waste the extra resources and processing power caused by the disorder.
The moral of the story: don't write bad code.
It should not be checked, because if it will be checked then the List interface and others needs to change to add throws to methods that would be overkill.
The exceptions like IndexOutOfBoundsException or NullPointerException should be prevented before they are thrown. These exceptions are RuntimeException that could be occurred when application is run depending on data and not intentionally. The circumstances in which these exceptions occur are unpredictable and cannot say if the code throws exception or not. That's why it should be runtime exceptions.
In you code, to be a valid code, you should check the bounds of index before you use an arbitrary index to access elements of the list. Use isEmpty() or size() to get the condition in which you should correct the flow.

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