The following method will warn about IOException if called in Java code but will simply ignore any warning in Kotlin because IOException is a checked exception.
ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_WRITE)
Java forces developers to take safe action in case it throws an exception but in Kotlin it just overlooks the exception creating a potential bug source. I'm quite sure there are lots of similar cases where checked exception is simply ignored.
The question is how to handle such cases?
Java will not warn you if method is throwing unchecked exception, how are you handling this case? The best you can do here is to check java doc or the source of the calling method to see if it throws any exceptions. Or just to catch any exception somewhere in your code which calls this method.
If you are asking why Kotlin doesn't have checked exceptions unlike java, the official Kotlin docs about exceptions provides an explanation why they decided to move away from checked exceptions. Quote:
Examination of small programs leads to the conclusion that requiring exception specifications could both enhance developer productivity and enhance code quality, but experience with large software projects suggests a different result – decreased productivity and little or no increase in code quality.
UPD: Article by kotlin lang architect about this matter: https://elizarov.medium.com/kotlin-and-exceptions-8062f589d07
Kotlin doesn't prevent you from catching any or all exceptions; it just doesn't force you to do so, like Java does.
So you can still do e.g.:
try {
ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_WRITE)
} catch (x: IOException) {
// …
}
As for how you know that the method could throw an IOException… that's tricky. If it's a Java method, then of course its JavaDoc will specify it (and you can see that from your IDE). But if it's Kotlin, well, the documentation might say; or if you have the source code, you could check that. But I'm afraid there's no real way to know! All you can do is guess — and ensure that you catch all exceptions at critical points.
Treating all exceptions as unchecked is not without controversy; see this long-running discussion.
There are clearly a few situations where Java-style checked exceptions would be impractical: for example, when calling lambdas or function references. (Java itself forces you to handle or wrap checked exceptions in such cases, which can be unwieldy.) For big programs which cover multiple layers of abstraction, there's the problem of exceptions bubbling up to a point where they make little sense; the usual solution there is exception translation: catching them and rethrowing more appropriate ones. And there's also the problem that too many bad developers simply catch all exceptions and ignore them (or, at best, log them) without considering how or where they should be handled.
But you might well think that dropping all exception checking is throwing the baby out with the bathwater…
(I've suggested that Kotlin should do exception inference — working out which uncaught exceptions a method could throw, and assuming a #Throws declaration for them — which would solve most of the problems around knowing which exceptions could be thrown at any point, without requiring them to be caught or invalidating any existing code. But I'm probably failing to see some problems around that, because while it seems an obviously good idea to me, it hasn't been well received…)
I want to know whether it would be right to use exception classes as regular classes to handle application errors (just regular controlled errors, not exceptional ones), without throwing them with the proper language clause (eg. instantiating them and returning them from a method). I've been discussing this topic recently with some colleges and I think that exceptions should only be used as exceptions, but I'd like to listen to more opinions.
What you mean by "controlled error" is actually known by the name checked exception.
"Exceptional exceptions" are known as unchecked exceptions.
The difference is explained here: Checked vs Unchecked exception
So, you see: Java comes with a built-in mechanism to distinguish between
exceptions caused by programming mistakes (e.g. NullPointerException when passing unexpected null as an argument) -- unchecked exceptions
versus anticipated exceptions that should be handled by the caller (e.g. IOException when some kind of I/O went wrong) -- checked exceptions
Returning instances of Exception (or any subclass) would be considered a misuse in virtually all circumstances.
You could ask your colleague how he/she would implement an exceptional outcome of a method with this signature:
public String createStringOrFailWithException();
Returning an Exception? Certainly not, because this requires a different return type.
Throwing the exception instead allows you to keep the return type, and to benefit from vast exception handling capabilities, including finally blocks and try-with-resources statements, to give only two examples that you don't want (should not) implement by yourself.
I suggest keeping Exceptions "exceptional". I.e. don't build them into your app logic. Use more meaningful things like a ActionXResponse class etc that could indicate failure, and even have an Exception as a property which the controller could check for "controlled exceptions". It's much more meaningful when you have your own class as a response.
Another guideline I'd suggest, along with keeping Exceptions "exceptional" is to avoid checked Exceptions (compile-time).
I am following this great discussion at SO, titled: The case against checked exceptions , but I am unable to follow where exactly RuntimeException should be used and how it is different from normal Exceptions and its subclasses. Googling gave me a complex answer, that is, it should be used to deal with programming logic errors and should be thrown when no Exception should normally occur, such as in the default block of switch-case construct.
Can you please explain RuntimeException in greater detail here. Thanks.
I am unable to follow where exactly
RuntimeException should be used
That's probably because you are looking at an argument, i.e. people are disagreeing about exactly this point.
and
how it is different from normal
Exceptions and its subclasses.
Very simple: All subclasses of Exception (except for RuntimeException and its subclasses) are checked i.e. the compiler will reject the code unelss you catch or declare them in the method signature. However, subclasses of RuntimeException are unchecked.
Googling gave me a complex answer,
that is, it should be used to deal
with programming logic errors and
should be thrown when no Exception
should normally occur, such as in the
default block of switch-case
construct.
This is the conventional wisdom, which says that for everything that a program can usefully deal with, you should use checked exceptions because then the compiler will force you to deal with them. Conversely, programs can typically not deal usefully with programmer errors, thus they don't have to be checked. This is how the Java Standard API uses RuntimeException.
The discussion you linked to is sparked by the view of some people (this includes me) who think that checked exceptions lead to bad code and should therefore not be used. Since you can't disable exception checking in the compiler, the only way to do this is to use only RuntimeException and its subclasses.
One observation that IMO supports this view is that the conventional wisdom of "use unchecked exceptions only for programmer error" is in fact mainly a rationalization of backwards-reasoning: there is no code safety reason why the compiler should not force you to deal with programmer errors. However, something like NullPointerException and ArrayIndexOutOfBoundsException can crop up almost anywhere, and if those were checked, nobody would ever want to program in Java. Thus, the language designers had to make a, huh, exception for those, and make them unchecked. To explain this, they came up with the "unchecked exceptions are for programmer errors" story.
Quotes from Effective Java 2nd Edition, Item 58: Use checked exceptions for recoverable conditions and runtime exceptions for programming errors
The Java programming language provides three kinds of throwables: checked exceptions, runtime exceptions, and errors. There is some confusion among programmers as to when it is appropriate to use each kind of throwable. While the decision is not always clear-cut, there are some general rules that provide strong guidance.
The cardinal rule in deciding whether to use checked exception or an unchecked one is this:
Use checked exceptions for conditions from which the caller can reasonably be expected to recover. By throwing a checked exception, you force the caller to handle the exception in a catch clause or to propagate it outward. Each checked exception that a method is declared to throw is therefore a potent indication to the API user that associated condition is a possible outcome of invoking the method.
Use runtime exceptions to indicate programming errors. The great majority of runtime exceptions indicate precondition violations. A precondition violation is simply a failure by the client of an API to adhere to the contract specified by the API specification.
Here's an example:
When trying to read a file of arbitrary name, the file may not exists. It's not strictly a programming error when a file does not exist (e.g. perhaps it did before but was then accidentally deleted). Clients may want to recover from this. Thus, FileNotFoundException is a checked exception.
If you give a null string as a filename, then NullPointerException (or perhaps an IllegalArgumentException -- another contentious debate) should be thrown. Client of the API is supposed to provide a valid string value; null isn't. As far as the API is concerned, this is a programmer error, which was easily preventable. Both of these exceptions are runtime exceptions.
Item 59: Avoid unnecessary use of checked exceptions also provides additional guidance:
Checked exceptions are a wonderful feature of the Java programming language. Unlike return codes, they force the programmer to deal with exceptional conditions, greatly enhancing reliability. That said, overuse of checked exceptions can make an API far less pleasant to use. If a method throws one or more checked exceptions, the code that invokes the method must handle the exceptions in one or more catch blocks, or it must declare that it throws the exceptions and let them propagate outward. Either way, it places a nontrivial burden on the programmer.
The burden is justified if:
the exceptional condition cannot be prevented by proper use of the API, and
the programmer using the API can take some useful action once confronted with the exception.
Unless both of these conditions hold, an unchecked exception is more appropriate.
So here's a short summary of the recommendation from Effective Java 2nd Edition:
Preventable exceptions that happen due to API user errors should be unchecked.
Exceptions that can't be handled reasonably should also be unchecked.
Otherwise, the exception should be checked.
See also
Effective Java 2nd Edition
Item 58: Use checked exceptions for recoverable conditions and runtime exceptions for programming errors
Item 59: Avoid unnecessary use of checked exceptions
Item 60: Favor the use of standard exceptions
Item 61: Throw exceptions appropriate to the abstraction
Item 62: Document all exceptions thrown by each method
Technical definition
An unchecked exception is defined as RuntimeException and its subclasses, and Error and its subclasses. They do not have to be declared in a method's throws clause.
References
JLS 11.2 Compile-Time Checking of Exceptions
Related questions
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
IllegalArgumentException or NullPointerException for a null parameter?
Is there any point in having a com.myco.myproj.MyProjRuntimeException,
which completley extends RuntimeException?
Yes. Do throw unchecked exceptions, and subclass them.
There is much talk about whether checked exceptions are really any good. In a nutshell, if I throw a checked exception, does my client really have anything to do with it?
Unchecked exceptions are a good way to notify your clients about exceptional situations (including illegal pre-conditions), and yet not burdening them with the need to wrap calls to your API with try-catch blocks, which most of the time basically serve no purpose, other than debugging, tracing, etc.
So why not throw a RuntimeException? It's not elegant, and it's less readable. Make it your own exception which derives from it, even if it's for no reason other than being more specific when throwing the exception.
It depends on if you want to handle the exceptional condition differently than other exceptions farther up the call stack. If you intend to catch and handle the exception, then I'd recommend creating the custom type. It makes for more legible code and cleaner catch clauses. If you're not going to catch the exception, then there's probably little reason to create a new type.
Not really. The extra information you get from having the exception name show up in a stack trace could be given by simply setting the message string of a standard RuntimeException. However (come to think of it), it might be useful to subclass RuntimeException simply to prepend a custom string onto any message.
I tend to only make custom checked exceptions; generally, the standard unchecked exceptions cover enough potential cases already.
Many people (me and the designers of C# included) believe that checked exceptions are a failed language experiment and avoid them. Then, creating your own exception hierarchy under RuntimeException is an obvious step.
in Effective Java, Joshua Bloch writes:
Use run-time exceptions to indicate
programming errors. The great majority
of run-time exceptions indicate
precondition violations.
That being said, you could use that run-time exception as a base class for a hierarchy of run-time exceptions, used in your project. That way, errors become more legible and traceable.
In my opinion, you should only create new Exceptions if you really need them, i.e. want to catch them and do a specific treatment on them. On all other cases, I don't really see the usefulness.
It's a good style to maintain your own exceptions hierarchy.
But I've seen just a few people who can use this technique with real profit.
Subclass exceptions based on how they are handled rather than who wrote them...
Normally runtime exception can't be handled in another way than logging the error and possibly display an error message.
Checked exceptions might possibly have a specific fallback, and in that case they should probly not subclass a "MyFrameWorkException" - as in that case, catching a MyFrameWorkException would not do more than the generic catch (logging etc.)
It is a rather bad practice to invent a whole hiearachy of exceptions that does have little in common except the fact that they belong to a particular framework.
(packages are supposedly used for just that.)
It is perfectly ok to subclass RuntimeException (if the existing subclasses are not a god fit)
Document unchecked exceptions. Be conservative with checked exceptions, and don't build hierarchies.
Rod Jonhson wrote on this in Expert one-on-one J2EE design and development and as in Tom's answer RuntimeException should be used for programming errors.
A good example is SQLException, lower level data access API should catch them and throw your own "SQLRuntimeException" as most of the time the calling code cannot do anything with the exception. This way, your higher level apis are not forced to catch or carry lower level exceptions in their signature, which make code simpler and more focused on the business domain.
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).