I'm trying to understand checked exceptions in Java and have the following query.
Is the following correct: If a method has the potential to throw a checked exception, of any type, that exception must either be
declared using the throws keyword, or
caught by the respective method.
If the above is correct, does this mean that I need to understand every single checked exception that is built in to Java so that I know whether my method will have the potential to throw that exception? Or should I just attempt to compile my code and then amend my code based on the compile-time errors?
If the above is correct, does this mean that I need to understand every single checked exception that is built in to Java [...]?
Yes, your statements are correct, but no one expects you to know of all potential checked exceptions when programming. And you don't have to if you have a compiler, or better, an IDE at hand.
Either you go back and forth between compiler output and code as you suggest in your question, or you install an IDE such as Eclipse which gives you direct notifications if you violate the rule:
does this mean that I need to understand every single checked exception that is built in to Java
I assume you are using some IDE (eg. Eclipse) - if not, you should get one ASAP.
Then, the IDE pretty much continuously compiles the code, so when there's a problem, you will get a red underline near it, and a tooltip bubble telling you what's wrong - eg "Missing throws".
Therefore, your second assumption is basically correct, it just happens behind the scenes:
Or should I just attempt to compile my code and then amend my code based on the compile-time errors?
So no, you don't need to learn all the exceptions.
Also, all checked Exceptions extend Exception, so if you have access to the source, you can check what they are based on. Non-checked exceptions extend RuntimeException.
Rule of thumb: If it's something with I/O, it's usually checked. That's the most common type of exception you will encounter.
whenever you use a method (whether your own or In-built) if you closely follow its method signature, if the method throws some exception you need to throw/handle it explicitly in your code
In this way you will not need to memorize all the exceptions and you will know which exceptions to handle where.
To make life easy use some IDE like eclipse
hope this helps!
Good luck!
If the above is correct
It is...
[...] does this mean that I need to understand every single checked exception that is built in to Java so that I know whether my method will have the potential to generate that exception? Or should I just attempt to compile my code and then amend my code based on the compile-time errors?
Use an IDE! You don't need to intimately know ALL of them.
What you do want to check however is the hierarchy (ie, check the javadoc! That should be a Pavlovian reflex); since exceptions are classes, they inherit one another and, for instance, FileSystemException is a portmanteau exception of java.nio.file to signal a filesystem related problem and it inherits IOException. Catch it before IOException if you want to treat it specially.
As a general rule, catch more specific exceptions first.
Also, DO NOT catch Exception. Never. The problem is that RuntimeException, which is the base exception for unchecked exceptions, inherits Exception, meaning that if you catch Exception you catch all unchecked exceptions. You want to rethrow unchecked ones:
try {
something();
} catch (RuntimeException unchecked) {
throw unchecked;
} catch (Exception e) {
// deal with e
}
Yes you need to know every exception..however if u know super class of that exception than you u don't need to know the subclass of it...for e.g..FileReader throws a exception called FileNotFoundException Since FileNotFoundException is a subclass of IOException, we can just specify IOException in the throws list and make the above program compiler-error-free.
Related
I've studied that: With an unchecked exception, however, the compiler doesn't force client programmers either to catch the exception or declare it in a throws clause. In fact, client programmers may not even know that the exception could be thrown. eg, StringIndexOutOfBoundsException thrown by String's charAt() method.
what its mean?
according to that code there is no need to put try catch block in code,
but i've seen compiler forces to put the code in try catch block.
I'm very confused what they are exactly?
Unchecked exceptions are those that extend RuntimeException class. Compiler will never force you to catch such exception or force you to declare it in the method using throws keyword. All other exception types (that do not extend RuntimeException) are checked and therefore must be declared to be thrown and/or catched.
Checked exceptions are used when you want the caller of your method (i.e the user of your API) to explicitly handle the exceptional case in your API. Checked exceptions are declared when you believe the call will be able to do something meaningful with that exceptional case, like retrying the call, rolling changes back or converting it into some user-readable error message.
If you believe that there is nothing useful the call can do about the exception (especially when it represents a bug, or a wrong usage of your API), then the exception should be unchecked. Also, an API with too many checked exceptions can be annoying to program with (e.g. try using java reflection API=)
Checked Exceptions are useful for handling events that occur in the normal operation of a program. An example would be an IOException that is thrown when a file cannot be opened. These exceptions occur even if there is nothing wrong with the program. It is necessary, therefore, to tell the program how to handle the exception.
Unchecked exceptions are useful for identifying defects in the code. For instance, a NullPointerException is thrown when a value is read on a null object. Thus an Unchecked Exception represents a problem that requires a manual fix by the programmer. It is reasonable for the program to crash in order to avoid erroneous behavior, so a try-catch block is not required (but might be desirable in order to provide mitigation, such as displaying an error to the user).
What is your question exactly?
Compilers shouldn't (and won't) enforce you to try/catch unchecked exceptions, that would go against exactly what they are.
The general idea is that checked exceptions are something you may be able to foresee but may be based on input that is out of your control and that you have to deal with.
Unchecked exceptions will usually represent bugs in your program.
There's a number of people that think checked exceptions are a mistake in the Java platform and they only use them very sparingly or not at all. You can read more about this debate by searching google.
It is because,
Unchecked Exceptions are not a result of programmer's fault. Instead they are the serious consequences where we(programmer) aren't expected to do much with it.
In case of Checked Exception, it is an exception generated because of the programmer's fault & often can be resolved by programmer itself.
Check the following links :
Why RunTime Exceptions are unchecked ?
Checked vs Unchecked Exception ?
All Exceptions are part of run time and not compile time. There are two kinds of exceptions checked exceptions and unchecked exceptions. Examples of checked exceptions are IO Exceptions, ClassNotFound Exception and examples of unchecked exceptions are runtime exceptions. In the case of checked exceptions, error or warning message comes at compile time so that the user will take care of it at runtime by using throws keyword, which is used to throw exceptions to the default catch mechanism system. But in case of unchecked exceptions warning is not there at compile time.
**Checked Exceptions
Exceptions which are to be checked or handled or should be taken care during the time of writing the code are called as checked exceptions.
For eg:
1. we have FileNotFoundException -->which will be occured when we are writing some code related to file classes. There will e defenetly posibility of non existence of file. In such case in order to handle them , we are forced to handle those exception for sure.
2. one more example is ParseException ,which will be occured when we are dealing with date functions.
UnChecked Exceptions
These are the exceptions that are optional to be handled during the time of coding. Its up to us whether we handle them or not. In case if we fail to handle them, There is a chance of getting runtime errors during the exceution.
For eg:
We have something called NullPointerException,ArithemeticException,NosSuchElementFoundException and so on. These are like optional things we dont even have to handle them. More over even jvm or compiler will not recommend us to handle them.**
in simple words,
checked exceptions are those which can be and should be handled by your code(therefore compiler forces you to handle them)
unchecked exceptions are those which lie beyond programmer's control(therefore compiler doesn't forces you to handle them)
use the same rule even while creating your custom exceptions.
I have a method which calls several other methods. However these methods and other operations (like navigating array or working with null pointers) can throw runtime exceptions which are not explicit.
One could make use of a try{...}catch(Exception e){...} block to make sure that no wild exception crosses the barrier and my method does not throw any exception which isn't explicit declared in its signature.
However this solution is ugly and prone to bugs since I may not want to catch everything or I may want to provide some specific behavior given a specific error situation.
So, is there a way for Eclipse to show me something like "careful, your method says that it throws IllegalArgumentException and JSONException, but you are missing some runtime exceptions that you can catch internally or declare that you throw them as well"? So far Eclipse only shows me which Exceptions I really must declare in the method's signature, but I also wanna be forced to declare the (Unchecked) runtime exceptions.
Ps.: This is not a duplicate of How can I know what exceptions can be thrown from a method? since the best solution there is to use a catch-all block.
Short answer is: you can't.
That is the nature of RuntimeException; they are not "checked" exceptions; therefore you are not enforced to add them to your throws clause.
The important thing is that on some level your code understands that RuntimeExceptions might occur; and deals with them in the correct way.
Example: assume you are working on "providers" that should process requests that are coming from a restful API.
There are now two types of problems:
A) those that you "expect" and where you give fine granular feedback on. For example your API spec might list many 400.xxx, 409.xxx, ... answers for various problems. It makes sense to use "checked" exceptions for these things (the code throwing an "ApiException" already knows that this error should show up as 409.xxx to the user of the restful API).
B) Then there are those that you "do not expect"; basically those are reflecting "bugs" in your code; like "he, this argument should not be null"; "he, this 'key' is unknown". For those ... just throw RuntimeExceptions. But make sure that your top layer catches them; and for example turns them into a 500.xxx answer to the user ("some internal error happened, here is the stacktrace; send us a bug report)
Your request has an interesting twist. You want to catch all exceptions that the invoked methods may throw, but you don’t want to use catch(Exception ex){ … } because that would imply that … you are catching all exceptions.
Let’s ask the other way round: which exception do you want to exclude from the catch clause? If you want to catch all checked exceptions as well as all runtime exceptions, you exclude Errors and those runtime exception which may not occur. Well, that’s what catch(Exception ex){ … }already does. It doesn’t catch Errors and you don’t need to bother about exceptions that are impossible to occur.
That said, there is a reason why you shouldn’t catch RuntimeExceptions. They are there to signal conditions that normally shouldn’t occur even if their impossibility can’t be proven at compile time.
If you want your IDE to collect all runtime exceptions that are in principle possible, consider
Every access to an object or array may cause a NullPointerException
Every array access may cause an ArrayIndexOutOfBoundsException or NegativeArraySizeException
Every array write access may cause an ArrayStoreException
Every integer division may cause an ArithmeticException
Every runtime type cast, including those hidden by Generics may produce a ClassCastException
etc. And these are only the exceptions associated with language constructs, not containing those possibly produced by library methods.
The set of possible exceptions will soon explode if you really ask a tool to collect them all for a particular piece of code and all invoked methods.
You would need an insanely large list of exception types in your catch clause and that only to hide the fact that you are actually attempting to catch all exceptions (as catch(Exception ex) would immediately make apparent)…
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'm building a scientific software with lots of calculations and of course arguments can have wrong lengths etc... So I used IllegalArgumentException class as it seemed right name for the issue, but should I put the throws IllegalArgumentException at the function definition ?
I am asking this because after I wrote it, the Eclipse Editor didn't ask me to surround the function with try and catch. I thought this is how try and catch were enforced. I've read the Exception handling tutorial at Java.com yet I'm not sure I understood the part regarding my question right though.
RuntimeExceptions like IllegalArgumentException are used to indicate programming errors. The program itself should rarely be able to handle it. Someone needs to manually fix the code.
Potential RuntimeExceptions should be documented somehow in the function contract (i.e. javadoc), either with the explicit #throws, or while describing the inputs. If you don't have a javadoc for the function, you may want to add the throws clause just to document the potential pitfalls of using the function, but in general adding throws clauses for runtime exceptions is discouraged.
If giving a wrong length is not actually a programming error, but is an exception situation, I would create a new checked exception (such as BadLengthError). If it is not an exceptional situation, don't use exceptions for flow control.
There's two types of exceptions:
runtime exceptions (like IllegalArgumentException and NullPointerException for example) don't need to be explicitly caught, because they 'shouldn't happen'. When they do, of course, you need to handle them somewhere.
regular exceptions NEED to be caught or declared to be thrown because they represent a more intrinsically difficult kind of error.
You need to read up on Unchecked Exceptions - exceptions which inherit from RuntimeException. They don't need to be declared in the method header.
http://download.oracle.com/javase/tutorial/essential/exceptions/runtime.html
The last paragraph sums it up:
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.
IllegalArgumentException (along with some others, for example NullPointerException) are examples of a RuntimeException. This type of exception is not what's known as a checked exception. Java requires that methods declare which checked exceptions they throw and that if a called method might throw a checked exception, the calling method should either declare that it throws the exception itself, or catch and handle it.
As such, my concrete recommendation would be no, don't declare it. Certainly, though, you don't want to be catching it. In most cases, you also don't want to be throwing it unless this is unexpected behaviour. If it's quite normal and reasonable for the the method to be getting a value it doesn't like, an Exception is the wrong way to handle it.
You might also want to consider making use of assertions.
the first point when understanding exceptions is that they are for exceptional situations. While thinking about your method you must ask: "Should this method throws an exception if an exceptional value is passed through?" If the answer is "yes", put it in your method declaration.
I don't know if you get the idea, but it's kind of simple. It's just a matter of practice.
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.