What is the guideline for methods declaring runtime exceptions?
Let's say I call a 3rd party routine that throws SQLException. Is it permissible/standard/acceptable for that routine to be able to throw RuntimeExceptions without declaring that it does so?
As always, I am surprised by the confusion my questions cause :-D This is probably because I am confused.
In the following, the callable is a lambda that issues a commit, and this throws SQLException. callable.call throws Exception.
private doThis(Callable<T> callable) throws SQLException {
try {
return callable.call();
} catch (SQLException e) {
// do stuff
throw e;
} catch (Exception e) {
break; // Eats any exception from call() which makes me scream internally.
}
}
What I surmise from this is that the coder wanted doThis to throw a SQLException. However, the nature of using the Callable meant that the routine had to throw an Exception unless the coder did something. So he caught Exception and swallowed it. But Exception is the parent is RuntimeException, so we're eating those too.
What am I to do? Making doThis throw Exception seems clumsy and random. Wrapping any exception being thrown in a RuntimeException and raising that preserves the coder's intent but seems suspect.
EDIT -
ok, I have learned, thank you. Now the question is, what to do about it. Clearly, eating the exception is a bad idea. Diluting the SQLException as declared seems not great.
How does the collective wisdom of SO feel about wrapping the Exception in a RuntimeException?
...
} catch (Exception e) {
throw new RuntimeException(e);
}
What am I to do? Making doThis throw Exception seems clumsy and random. Wrapping any exception being thrown in a RuntimeException and raising that preserves the coder's intent but seems suspect.
This method's sole reason for existence appears to be to perform special handling (// do stuff) in case of a SQLException. To handle that error correctly, some assumptions about what the Callable is doing must hold. For the sake of argument, perhaps the "stuff" is marking a particular database connection for rollback, assuming that the Callable used it do some work that may have partially failed.
Yet, this method accepts Callable. That doesn't impose any limitation on what the called function might do, why it might throw a SQLException, or what a SQLException might mean if it does arise. This code feels wrong, because it is wrong to make these very specific assumptions about an open-ended, black-box function like Callable. And, it's probably unnecessary. This is a private method, so you know everything about the methods that call it, and you can modify them to make it clear how things work together.
Instead, define your own (functional) interface. Declare the specific exceptions your helper method can handle, and document any other requirements for implementations. If, in fact, the "stuff" done in your helper method involves a database connection that is a member of the object, you might define the interface like a Consumer or Function, but with SQLException or other errors.
Here's a hypothetical example:
private final Connection db;
#FunctionalInterface
private interface DatabaseOperation<T> {
T apply(Connection db) throws SQLException;
}
private <T> T withRollback(DatabaseOperation<T> op) throws SQLException {
try {
return op.apply(db);
} catch (SQLException ex) {
db.rollback();
throw ex;
}
}
None of this is to say that Callable or other core functional interfaces are bad. You shouldn't create new, non-standard functional interfaces when the pre-defined interfaces would meet your needs. It's just that they don't in this case.
Not sure what you mean.
Is it okay to stick exception types that extend RuntimeException in the throws clause of a method?
Java implies certain things and usually you can't undo these things.
For example, all java files act like they have import java.lang.*; at the top even if don't write that. All classes that don't have an extends clause act like they have extends java.lang.Object...
and all methods act like you have throws RuntimeException, Error on them whether you write it or not.
It's legal to write import java.lang.*;, although it would be completely pointless to do this. It is similarly legal to write:
void foo() throws RuntimeException {}
even though this is rather pointless. However, unlike import java.lang.*;, adding some specific runtime exception can be useful in the sense that it documents (It has absolutely no effect whatsoever on what the code does). Some linting tools (I would disagree with the style they are espousing, though!) flag it down as 'useless code' but I wouldn't be so hasty. For example, this method:
public static int parseInt(String in) throws NumberFormatException {
..
}
is declaring the NFEx for no programmatic purpose (NFEx is a RuntimeException and all methods trivially can throw those without declaring them), but it is documentary: It highlights that that's an exception you should be taking into consideration when invoking this method / it's the obvious "thing you are looking for" (in the sense that 'soooo... what if I pass a string that does not contain a number to this method, what happens then' - is the obvious question to ask).
So, do it, if that's your intent. Your javadoc should probably have a:
* #throws NumberFormatException If the provided {#code input} is not parseable as an integer number.
or similar, for each explicit RuntimeException you care to state.
Is it okay to wrap SQLException to RuntimeException
Usually: No. The notion of declared checked exceptions is that they are part of your signature. A signature is all about what a method does. It is very much not at all about how it does so.
Thus, the crucial question to ask is: Is the SQLException aspect of it fundamental to what your method does, or fundamental to how it does it?
A trivial example:
saveGame() may simply 'save your game to some persistent storage mechanism'. That's what it does. Perhaps the how involves a database today. Perhaps tomorrow it'll involve the file system. Perhaps next year it's a cloud save system and it involves network access. If the point of this method is merely to force a save, and the method's signature intentionally does not explain how (because you want the future flexibility of changing this, and thus any callers should not assume it's disk, or DB, or network, or anything else), then and only then: SQLException would purely be about the how - and thus it has no place being thrown from the saveGame method. You should wrap it. I highly doubt it's a good idea to wrap that in RuntimeException, I'd invent your own exception (SaveGameException perhaps). Should that exception be checked or unchecked? That depends on too many factors to get into for this answer.
However, something like Files.newOutputStream is different. The what of this method includes the notion that its file based. Fundamentally: It would be nuts if that method doesn't interact with a file system at all and instead opens a database connection. The very name of that method spells it out: It is, after all, in a class named Files - the fact that it interacts with files is a fundamental, unremovable aspect of it. Hence, that method should most absolutely be declared to throws IOException. Similarly, if you have a method called saveToDb, that method should definitely be declared as throws SQLException - and thus, you should not be wrapping your SQLException in anything else.
In rare cases, convenience and intended usage strongly dictates you do not want the exception to be checked. In that case, make an unchecked variant and wrap that. Java itself has UncheckedIOException already - reuse that if it's about IOExceptions. Write the same principle if its about SQLException. However, usually if this comes up you've badly designed your classes - if there's an aspect of your system that is fundamentally tied closely to the notion of interacting with DBs, that entire chain of methods should all be declared to throws SQLException, at which point the need to make that unchecked no longer exists.
Can RuntimeExceptions happen?
Yes, by their nature, RuntimeExceptions can happen at any time. Looking at the greater java ecosystem, RuntimeExceptions cover 3 mostly separate use cases (this isn't getting into what the feature was ever intended for, this is solely about what common java libraries and code actually use them for):
Programming errors (bugs)
The quintessential example is NullPointerException. There is a bug, the bug should cause some kind of RuntimeException to be thrown. We do not want to make such exceptions checked (because nobody likes a catch block that literally is impossible to trigger unless you actively write bugs to do so - what could you possibly stick in the catch block?), but we DO want to throw something: Breaking off the method and 'unrolling' the entire call stack until some general handler deals with the problem (and gets lots of details about where that problem occurred and why) is precisely what we want. Hence, exception good, checked bad - these should be runtime exceptions and generally are.
Similar examples: Many methods that have rules about what you can pass to them which cannot be expressed in the type system (say, a method that requires you pass a non-negative integer) will throw IllegalArgumentException if you pass a negative number to them, for example. Some methods cannot be called when the object is in a certain state, and will throw IllegalStateException or UnsupportedOperationException, both unchecked (subtypes of RuntimeException) - for example, if you attempt to invoke .add() on an immutable list, you'd get that.
Couldn't be bothered
Sometimes checked exceptions can occur but you just don't care, either because you're a lazy programmer who wants to just go home (that'd be quite bad, of course), or because you cannot fathom why a checked exception could occur. For example, an IOException when writing to an OutputStream that is memory based.
IDEs tend to suggest this incredibly stupid 'fix':
try {
code();
} catch (IOException e) {
e.printStackTrace();
}
I do not know why. Mass delusion? At any rate, all IDEs are very wrong, that is bad code, the correct 'I do not want to think about this checked exception right now' handle block is throw new RuntimeException("uncaught", e); - and smart folks have updated their IDEs to auto-generate this. It's wrapping a checked exception in an unchecked one simply for convenience, or because the coder did not think it could happen.
For API/programming model reasons
See UncheckedIOException - usually because the code is designed to be used in stream pipelines which doesn't allow checked exceptions. Somewhat rare.
Unexpected situations
It could be reasonable for the programmer of this library to fail to account for some exotic situation which nevertheless is also reasonable for your specific usage of some library to run into. For example, a third party library could be saving data to whatever OutputStream you provide for it, and that OutputStream might throw a documented unchecked exception for some reason - in which case your library is likely to also throw it. This is rare - you'd presumably know about it, and it comes up only if some library is 'intermediary' - you pass it some object that it, in turn, acts upon, and in that interaction, the runtime exceptions end up getting passed through. Or, the object you pass in doesn't adhere to certain rules. For example, if I hand a comparator that doesn't adhere to the spec (for example, is inconsistent: both a.compareTo(b) and b.compareTo(a) return a negative number - the Comparator spec says you should not do that) to some library, and that library ends up throwing some undocumented unchecked exception for this, I wouldn't blame the library author.
The 'first' case (code bugs) should be documented. For example, Integer.parseInt indeed documents that a NumberFormatException is thrown if you pass a string that doesn't contain something parseable to an int. List's add documents that it might not be supported in which case UnsupportedOperationException will be thrown, etcetera. If your 3rd party routine's docs don't state anything, then it does not apply (or it is badly documented).
The 'second' case (laziness) is hopefully not the case either - that would mean the programmer of it did a bad job.
The third case should also be documented.
That leaves the 4th case, which could happen and won't be documented. You have some control over this, though.
CONCLUSION: Well written libraries will not be throwing undocumented RuntimeExceptions that you didn't expect (i.e. where you aren't the direct cause of it by handing weird objects or things that don't fit clearly documented specs)
Related
Why does the Java compiler allow exceptions to be added via throws even when they're not possibly able to be thrown?
example:
private static void foo() throws java.io.FileNotFoundException {
System.out.println("no possible FileNotFoundException here");
}
The above code compiles just fine, but it's not possible for a FileNotFoundException to be thrown.
I would suggest maintenance: because you might want to change that method later to add an operation that could throw a FileNotFoundException, and you want to force all callers of this method to know what to do if that method should be changed to throw FileNotFoundException in the future.
Another manifestation of the issue is that a subclass may override this method and throw the exception, and this cannot be determined by compiling the superclass alone.
Because the compiler isn't smart enough to find out every exception?
It sounds quite logical that Java can't know the possible outcomes for all algorithms. Just like a programming language can never prove a mathematical exception, it can only execute mathematics.
This means that an obvious mathematical "infinite loop", isn't always obvious to the programming language. I think that for such reasoning, the compiler doesn't bother looking at what will be executed.
If the compiler would have to pre-check for all exceptions the coder writes, it might spend "days" checking the code. All in all it just seems better to have the programmer responsible for the exceptions. Either way, it doesn't hurt.
Checked exceptions are validated by the compiler only in the try { } block, method bodies are not validated. There are multiple reasons, the complexity of such check being one, the fact that a child class can override the method and decide to throw the exception is a second.
In Netbeans 7.3.1, this would show up as an "unreported exception" and it will warn you that it must be caught or declared. So it would be an error. It depends on your tool.
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).
I find that Java's reflection API is exception verbose, and I often want to catch each specific exception, but just throw Exception. Is this poor practice, or do you really throw all of those exceptions on the method signature? Every method that calls that method must then deal with each of those specific exceptions in some way. Instead, I'm thinking of doing this:
public void someMethod()
throws Exception {
try {
// do a bunch of reflection...
} catch(ClassCastException classCastException) {
throw new Exception("Some specific message.", classCastException);
} catch(InvocationTargetException invocationTargetException) {
throw new Exception("Some specific message.", invocationTargetException);
}
}
Is that poor practice?
Rethrowing different kinds of exceptions that a method throws as a single unified exception can sometimes be a reasonable approach.
Using java.lang.Exception specifically for this is a bad idea, because it's too unspecific.
You might rethrow each different exception as some custom MyException or something like that. That's sometimes a reasonable approach when you're not really interested in why someMethod failed.
Short answer
Reflection is verbose by design
Exception translation is idiomatic (catching lower level exception and abstracting it to a higher level)
... but don't overuse!
Prefer custom exceptions to java.lang.Exception; it's probably too high of an abstraction
Point 1: Avoid reflection if at all possible
Here's a quote from Effective Java 2nd Edition, Item 53: Prefer interfaces to reflection:
[The power of reflection], however, comes at a price:
You lose all the benefits of compile time checking, including exception checking.
The code required to perform reflective access is clumsy and verbose. It is tedious to write and difficult to read.
Performance suffers. Reflective method invocation is much slower than normal method invocation.
[...] As a rule, objects should not be accessed reflectively in normal application at runtime. There are a few sophisticated applications that require reflection. Examples include [omitted on purpose]. If you have any doubts to whether your application falls into one of these categories, it probably doesn't.
Point 2: Exception translation can be a good thing, but don't overuse
Here's a quote from Effective Java 2nd Edition, Item 61: Throw exceptions appropriate to the abstraction.
It is disconcerting when a method throws an exception that has no apparent connection to the task that it performs. This often happens when a method propagates an exception thrown by a lower-level abstraction. [...]
To avoid this problem, higher layers should catch lower-level exceptions and, in their place, throw exceptions that can be explained in terms of higher-level abstraction. This idiom is known as exception translation.
[...] While exception translation is superior to mindless propagation of exceptions from lower layers, it should not be overused. Where possible, the best way to deal with exceptions from lower layers is to avoid them, by ensuring that lower-level methods succeed. [...]
If it is impossible to prevent exceptions from lower layers, the next best thing is to have the higher layer silently work around these exceptions, insulating the caller of the higher-level method from lower-level problems. Under these circumstances, it may be appropriate to log the exception using some appropriate logging facility. This allows an administrator to investigate the problem, while insulating client code and end user from it.
Point 3: java.lang.Exception is way too general
Looking at the documentation, one can see a long list of direct known subclasses, with a wide-ranging topics from Reflection, RMI, XML parsing, I/O, GUI, cryptography, etc.
Declaring that a method throws Exception is probably a poor API design decision, because it does not immediately tell the user anything useful about what category the exceptions may be, or under what circumstances they may be thrown. Contrast this with a hypothetical ReflectionException; this is a lot more informative, and it also allows user to catch specifically ReflectionException and not, say, an IOException that somehow slipped through.
Related questions
In Java, is using throws Exception instead of throwing mulitple specific exceptions good practice?
Catching several exceptions and rethrowing a general exception
java.lang.Exception vs. rolling your own exception
When should Throwable be used instead of new Exception?
Need authoritative source for why you shouldn’t throw or catch java.lang.Exception
In Java, when should I create a checked exception, and when should it be a runtime exception?
When to choose checked and unchecked exceptions
The case against checked exceptions
I agree with your approach, except I think throwing Exception is not good, eventually every method declaration in your application will end with "throws Exception". For cases like this, where the exception will only occur if you made an error, it's better to make the wrapping exception an unchecked exception.
If the exception thrown by the method (contained in the InvocationTargetException) have the potential to be interesting to you, you could make it the wrapper a different subclass of unchecked exception or create a specific checked exception subclass for it, but wrap things like the ClassCastException in unchecked exceptions.
To use throws Exception is always a bad idea. In your case you have to consider the following things.
Can I recover from the error at the next imediate level? If so use all the different exceptions for clarity.
Can I recover from the error some levels up? If so use a wrapper exception because it would pollute all methods on the way up with technical details to use the explicit ones.
I can't recover from the error or it happens in a completely different place/many levels above. If wrap each exception into RuntimeException or a custom ReflectionFailedRuntimeException to avoid technical exceptions leaking throughout your application.
Alos, normally you should code it in a way that you can expect the reflection to work in most cases without Exceptions, so it would be also considerable to make it RuntimeException wrapping anyway.
Think of what you want to achieve. The caller of your method is not supposed to know you're using reflection to achieve your goal. That's none of its business. If you would just put all those exceptions in your throws clause that would break that encapsulation.
Catching these exceptions and wrapping them in your own is therefore the way to go. Then you just have to decide which exception to throw. Exception itself is a very bad idea (I'm of the opinion it should even be abstract to suggest that) The type of the exception should be related to the problem.
Throw an exception that relates to what you're trying to do and to why it failed (if it failed because a given argument is inappropriate, IllegalArgumentException would be one). Also make an informed decision on whether you would like to throw a checked or an unchecked exception (RuntimeException).
I would in some cases.
The normal way I would decide is look at what methods calling someMethod() would expect or reasonably be expected to know. So if someMethod() was doing something IO related I'd throw an IOException, if it was related to a library I was writing I might throw a custom exception..
I'd only throw the individual exceptions if the callers of someMethod() would reasonably be expected to know it used reflection for its implementation.
I guess the key question is "If someMethod() didn't use reflection, and something went wrong, what would it do?" That will normally give you the answer.
Thats still an acceptable policy if you are collecting all exceptions and throwing a custom exception of yours.
public void someMethod()
throws MyCustomException {
try {
// do a bunch of reflection...
} catch(ClassCastException classCastException) {
MyCustomException ex1 = new MyCustomException("Some specific message.", classCastException);
// Logic to add more details to exception AND/OR handling current exception.
throw ex1;
} catch(InvocationTargetException invocationTargetException) {
MyCustomException ex1 = new MyCustomException("Some specific message.", classCastException);
// Logic to add more details to exception AND/OR handling current exception.
throw ex1;
}
}
Generally catching exception should be for a reason of handling them in some way. Simply re-throwing an exception of larger scope makes no sense anywhere to me.
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).
At what point would you create your own exception class vs. using java.lang.Exception? (All the time? Only if it will be used outside the package? Only if it must contain advanced logic? etc...)
I think you need to ask yourself a slighly different question "What advantage does creating a new exception give me or developers who use my code?" Really the only advantage it gives you or other people is the ability to handle the exception. That seems like an obvious answer but really it's not. You should only be handling exceptions that you can reasonably recover from. If the exception you throw is a truly fatal error why give developers a chance to mis-handle it?
More in depth discussion: Custom exceptions: When should you create them?
Reason one:
Need to catch specific stuff. If calling code needs to deal with a specific exceptional condition, you need to differentiate your Exception, and Java differentiates exceptions with different types, so you need to write your own.
Basically, if someone has to write:
catch(ExistingException e) {
if({condition}) {
{ some stuff here}
}
else {
{ different stuff here}
}
}
You probably want to write a specific extension; catch Exception matching is clearer than conditionals, IMHO.
Remember: your new Exception can be a subclass of RuntimeException
Reason two:
API consolidation. If you write an interface and you have several implementations, it's possible that they will call different APIs with a whole bunch of different non-RuntimeExceptions thrown:
interface MyInterface {
void methodA();
}
class MyImplA {
void methodA() throws SQLException { ... }
}
class MyImplB {
void methodA() throws IOException { ... }
}
Do you really want MyInterface.methodA to throw SQLException and IOException? Maybe then it makes sense to wrap the possible exceptions in a custom Exception. Which again can be a RuntimeException. Or even RuntimeException itself...
I believe that:
catch (Exception e) {
...
}
... is an antipattern that should be avoided. You might want one centralized broad catch somewhere in your application, to log an error and prevent the whole application from terminating - but having them scattered around willy-nilly is bad.
Why:
try {
if(myShape.isHidden()) {
throw new Exception();
}
// More logic
} catch (Exception e) {
MyApp.notify("Can't munge a hidden shape");
}
So you try this, and due to a coding error, myShape is null. A NullPointerException gets thrown when the runtime tries to derefence myShape. This code reports a hidden shape, when it should be reporting a null pointer.
Either make your own exception, or find a suitably specialized exception in the API. It's not as if extending Exception or RuntimeException is onerous.
When I want to treat my exceptions differently from everybody else's. If I want to catch mine and propagate everyone else's, or if I want to catch someone else's and propagate mine, or if I want to catch both but treat them differently, then I will define a separate class for my exceptions. If I want to treat them all the same, either by propagating both or by catching both (and doing the same thing either way with the caught exceptions), the I will use the standard class.
IF there is an existing Exception with the language runtime or libraries, use it ELSE create your own, document it well and that should work in 99% of the cases.
Software captures meaning.
There are almost no reasons for throwing an existing exception: the JVM already does that for you. Your version of their exception isn't really accurate and throwing "Exception" isn't meaningful, either.
You might have a DataFormatException because of a parsing algorithm you wrote. This, however, is rare.
When your program encounters an exceptional situation, it's almost always unique to your program. Why force-fit your exceptional situation into an existing exception? If it's unique to your program, then... well... it's unique. Name it that way.
Do not, however, provide a unique exception class for each unique message. One exception class can have many variant messages and supporting details.
The Python rule of thumb, translated to Java, is to define any unique exceptions at the package level. [In Python, they suggest exceptions at the "module" level, something that doesn't precisely translate to Java.]
Start always by using the common exception classes and then when a need appears to handle it specially, change it.
When creating a method first time, just let exceptions go through.
If there are exceptions that must be handled, those can either be just defined in throws or wrapped to some runtime exception or wrapped own throws exception. I prefer runtime exceptions in many cases. Defining throws definition should be avoided until there is a need for it from API point of view.
Later when a need appears to do specific handling for an exception in some caller, come back and create new exception for it.
The point is to avoid doing extra work before knowing what is needed.
I can't imagine specifically throwing a java.lang.Exception if some object/class/method had a problem. It's too generic - if you're not going to create your own Exception class, seems to me like there ought to at least be a more specific Exception-type in the API.
I would use the exceptions from the Java API when the exception relates to the API. But if an exceptional situation arises that is unique to my own API then I will create an Exception for it. For example if I have a Range object with two properties min and max and the invariant min <= max then I will create an exception InvalidRangeException.
When I am writing code this helps because I know if the exception originates because I violated one of my own conditions or its something from the Java API.
In most cases it doesn't make sense to create your own exception class.
There is a tendency in novice programmers to create their own exception class just so they can use a name that is more indicative of the type of error. So you'll find classes like FTPInitializationException, DAOFactoryException etc. even though such exceptions are not being handled differently than standard exceptions. This is clearly an anti pattern that should be avoided.