Why is it not necessary to catch the IllegalArgumentException? - java

I wonder why the IllegalArgumentException class does not need to be catched or declared, while other exceptions have to (eg java.net.MalformedURLException).
public void foo() {
throw new IllegalArgumentException("spam");
}
public void bar() throws MalformedURLException { // required
throw new MalformedURLException("ham");
}
I know that Errors do not have to be declared because they are not intended to be catched.
I'd like to declare a new exception which also does not require to be catched.

There are two types of Exceptions in Java: Checked Exceptions and Unchecked Exceptions. Checked exception has to be caught or declared to be thrown (like MalfomedURLException) but catching Unchecked exceptions (like IllegalArgumentException) is not mandatory and you can let the caller catch them (or throw them up to its own caller).
For more information, take a look at this post:
Java: Checked vs Unchecked Exceptions Explanation
If you inherit your custom exception class from RuntimeException or any exception class inherited from it, then catching your exception will not be mandatory.

IllegalArgumentException is unchecked exception , so if you do not catch it then it will be handled by JVM , these exceptions are sublclasses of RuntimeException, Error, while MalformedURLException is checked exception which must be caught by programmer.All IOExceptions are checked exceptions Read here for more info

Related

What does "error: unreported exception <XXX>; must be caught or declared to be thrown" mean and how do I fix it?

New Java programmers frequently encounter errors phrased like this:
"error: unreported exception <XXX>; must be caught or declared to be thrown"
where XXX is the name of some exception class.
Please explain:
What the compilation error message is saying,
the Java concepts behind this error, and
how to fix it.
First things first. This a compilation error not a exception. You should see it at compile time.
If you see it in a runtime exception message, that's probably because you are running some code with compilation errors in it. Go back and fix the compilation errors. Then find and set the setting in your IDE that prevents it generating ".class" files for source code with compilation errors. (Save yourself future pain.)
The short answer to the question is:
The error message is saying that the statement with this error is throwing (or propagating) a checked exception, and the exception (the XXX) is not being dealt with properly.
The solution is to deal with the exception by either:
catching and handling it with a try ... catch statement, or
declaring that the enclosing method or constructor throws it1.
1 - There are some edge-cases where you can't do that. Read the rest of the answer!
Checked versus unchecked exceptions
In Java, exceptions are represented by classes that descend from the java.lang.Throwable class. Exceptions are divided into two categories:
Checked exceptions are Throwable, and Exception and its subclasses, apart from RuntimeException and its subclasses.
Unchecked exceptions are all other exceptions; i.e. Error and its subclasses, and RuntimeException and its subclasses.
(In the above, "subclasses" includes by direct and indirect subclasses.)
The distinction between checked and unchecked exceptions is that checked exceptions must be "dealt with" within the enclosing method or constructor that they occur, but unchecked exceptions need not be dealt with.
(Q: How do you know if an exception is checked or not? A: Find the javadoc for the exception's class, and look at its parent classes.)
How do you deal with a (checked) exception
From the Java language perspective, there are two ways to deal with an exception that will "satisfy" the compiler:
You can catch the exception in a try ... catch statement. For example:
public void doThings() {
try {
// do some things
if (someFlag) {
throw new IOException("cannot read something");
}
// do more things
} catch (IOException ex) {
// deal with it <<<=== HERE
}
}
In the above, we put the statement that throws the (checked) IOException in the body of the try. Then we wrote a catch clause to catch the exception. (We could catch a superclass of IOException ... but in this case that would be Exception and catching Exception is a bad idea.)
You can declare that the enclosing method or constructor throws the exception
public void doThings() throws IOException {
// do some things
if (someFlag) {
throw new IOException("cannot read something");
}
// do more things
}
In the above we have declared that doThings() throws IOException. That means that any code that calls the doThings() method has to deal with the exception. In short, we are passing the problem of dealing with the exception to the caller.
Which of these things is the correct thing to do?
It depends on the context. However, a general principle is that you should deal with exceptions at a level in the code where you are able to deal with them appropriately. And that in turn depends on what the exception handling code is going to do (at HERE). Can it recover? Can it abandon the current request? Should it halt the application?
Solving the problem
To recap. The compilation error means that:
your code has thrown a checked exception, or called some method or constructor that throws the checked exception, and
it has not dealt with the exception by catching it or by declaring it as required by the Java language.
Your solution process should be:
Understand what the exception means, and why it could be thrown.
Based on 1, decide on the correct way to deal with it.
Based on 2, make the relevant changes to your code.
Example: throwing and catching in the same method
Consider the following example from this Q&A
public class Main {
static void t() throws IllegalAccessException {
try {
throw new IllegalAccessException("demo");
} catch (IllegalAccessException e){
System.out.println(e);
}
}
public static void main(String[] args){
t();
System.out.println("hello");
}
}
If you have been following what we have said so far, you will realise that the t() will give the "unreported exception" compilation error. In this case, the mistake is that t has been declared as throws IllegalAccessException. In fact the exception does not propagate, because it has been caught within the method that threw it.
The fix in this example will be to remove the throws IllegalAccessException.
The mini-lesson here is that throws IllegalAccessException is the method saying that the caller should expect the exception to propagate. It doesn't actually mean that it will propagate. And the flip-side is that if you don't expect the exception to propagate (e.g. because it wasn't thrown, or because it was caught and not rethrown) then the method's signature shouldn't say it is thrown!
Bad practice with exceptions
There are a couple of things that you should avoid doing:
Don't catch Exception (or Throwable) as a short cut for catching a list of exceptions. If you do that, you are liable catch things that you don't expect (like an unchecked NullPointerException) and then attempt to recover when you shouldn't.
Don't declare a method as throws Exception. That forces the called to deal with (potentially) any checked exception ... which is a nightmare.
Don't squash exceptions. For example
try {
...
} catch (NullPointerException ex) {
// It never happens ... ignoring this
}
If you squash exceptions, you are liable to make the runtime errors that triggered them much harder to diagnose. You are destroying the evidence.
Note: just believing that the exception never happens (per the comment) doesn't necessarily make it a fact.
Edge case: static initializers
There some situations where dealing with checked exceptions is a problem. One particular case is checked exceptions in static initializers. For example:
private static final FileInputStream input = new FileInputStream("foo.txt");
The FileInputStream is declared as throws FileNotFoundException ... which is a checked exception. But since the above is a field declaration, the syntax of the Java language, won't let us put the declaration inside a try ... catch. And there is no appropriate (enclosing) method or constructor ... because this code is run when the class is initialized.
One solution is to use a static block; for example:
private static final FileInputStream input;
static {
FileInputStream temp = null;
try {
temp = new FileInputStream("foo.txt");
} catch (FileNotFoundException ex) {
// log the error rather than squashing it
}
input = temp; // Note that we need a single point of assignment to 'input'
}
(There are better ways to handle the above scenario in practical code, but that's not the point of this example.)
Edge case: static blocks
As noted above, you can catch exceptions in static blocks. But what we didn't mention is that you must catch checked exceptions within the block. There is no enclosing context for a static block where checked exceptions could be caught.
Edge case: lambdas
A lambda expression (typically) should not throw an unchecked exception. This is not a restriction on lambdas per se. Rather it is a consequence of the function interface that is used for the argument where you are supplying the argument. Unless the function declares a checked exception, the lambda cannot throw one. For example:
List<Path> paths = ...
try {
paths.forEach(p -> Files.delete(p));
} catch (IOException ex) {
// log it ...
}
Even though we appear to have caught IOException, the compiler will complain that:
there is an uncaught exception in the lambda, AND
the catch is catching an exception that is never thrown!
In fact, the exception needs to be caught in the lambda itself:
List<Path> paths = ...
paths.forEach(p -> {
try {
Files.delete(p);
} catch (IOException ex) {
// log it ...
}
}
);
(The astute reader will notice that the two versions behave differently in the case that a delete throws an exception ...)
More Information
The Oracle Java Tutorial:
The catch or specify requirement
... also covers checked vs unchecked exceptions.
Catching and handling exceptions
Specifying the exceptions thrown by a method

SONAR extend Exception or RuntimeException?

I have a custom exception class written as
public class MyCustomException extends RuntimeException {
public MyCustomException(Throwable cause) {
super(cause);
}
enter code here
/**
* #param message
* #param cause
*/
public MyCustomException(String message, Throwable cause) {
super(message, cause);
}
}
In my serviceImpl layer
#Override
public List<SiteDetails> getSite() throws MyCustomException {
}
SONAR (Ecplise IDE plugin for linting) states:
Remove the declaration of thrown exception '.MyCustomException' which
is a runtime exception
Should I remove the declaration or should I extend Exception in MyCustomException class instead of RunTimeException?
The sonar issue is very very primarily opinion based.
A RuntimeException is not forced to be handled and so declared but it is not a bad practice to declare it in a method to document this case.
Should I remove the declaration or should I extend Exception in
MyCustomException class instead of RuntimeException
If you deem that MyCustomException is an exception that has to be necessarily handled by the client, MyCustomException should derive from Exception rather thanRuntimeException .
Otherwise if the exception cannot be handled by the client in most of circumstances, you should remove the declaration to make Sonar Happy or mark (at least trying) this issue as a false positive if you think that it makes sense to convey the exception even if it is a RuntimeException.
I had same situation, you have to catch the runtime exception, in my case was an Array Out Of Bound Exception due to I'm parsing a string separated from special char value but sometimes the string value is not corresponding to the right convention, right? So I must handle it, but Sonar was blaming me for the same reason! ArrayIndexOutOfBoundsException is derived from runtime exception
, anyway once you know that your block of code could retrieve some runtime exception, instead of throw it directly, use a catch block and into this just throw your custom exception.
catch (ArrayIndexOutOfBoundsException e) {
throw new YourCustomException("your message",e);
}
In this way you can remove the throws signature on your method, and Sonar will be happy

Checked Exception 2 kinds of behaviours

I have noticed that there are 2 kinds of checked exceptions:
1)
public static void main (String []args)
{
try{
//no exception thrown here, it still compiles though.
}
catch(Exception e){System.out.println(e);}
}
2)
public static void main (String []args)
{
try{
// it does not compile if not written any code which potentially might throw it
}
catch(IOException io){System.out.println(io);}
}
Is there any rule to anticipate this behaviour? to know in advance which is not mandatory to be present and it is?
Hope I have been quite clear with explaining the issue.
Thanks,
Indeed ItIs
The Java Language specification states
It is a compile-time error if a catch clause can catch checked
exception class E1 and it is not the case that the try block
corresponding to the catch clause can throw a checked exception class
that is a subclass or superclass of E1, unless E1 is Exception or a
superclass of Exception.
The code compiles fine with Exception, because it is a super class of all Checked and Unchecked exceptions. So, a catch clause with Exception can handle the unchecked exception too. And for Unchecked exception, compiler cannot check at compile time that the exception is thrown or not. So, it won't give any error for Exception.
You can even try this with RuntimeException:
try {
} catch (RuntimeException e) {
}
... this will compile too.
From JLS Section 11.2.3 - Exception Checking:
It is a compile-time error if a catch clause can catch checked exception class E1 and it is not the case that the try block corresponding to the catch clause can throw a checked exception class that is a subclass or superclass of E1, unless E1 is Exception or a superclass of Exception.
Exception is a checked exception itself, but is also the superclass for RuntimeException and other unchecked exceptions.
1) In the first case, because the Exception class hierarchy includes RunTimeException, the compiler cannot conclude that an Exception will not be thrown in your try { ... } block. So, it must allow the code.
It can confirm the positive case (if you call a method that declares throws Exception or a non-run-time subclass), but it cannot confirm the negative case.
2) In the second case, it can conclude at compile-time that IOException will not be thrown in the try { ... } block, because IOException (nor any other checked exception besides Exception itself) is not the superclass for any run-time exceptions.
Of the following behaviors, I believe that Exception is the only special case with a combination of the two types:
If thrown:
1A. Does not need to be declared or
1B. Must be declared
If declared:
2A. Does not need to be thrown or
2B. Must be thrown
If not thrown:
3A. May be caught or
3B. Must not be caught
RuntimeException: 1A, 2A, 3A
Any other checked exception: 1B, 2B, 3B
Exception: 1B, 2A, 3A
More info on checked vs. unchecked exceptions in this answer: https://stackoverflow.com/a/6116020/143295

Which all comes under unchecked exception?

I had a discussion with one of the seniors on Exception in Java on concept
If I create a class by extending Exception class then it will be checked exception
If I create a class by extending Throwable,RuntimeException, or Error, then it will be unchecked Exception
Is the above statements correct ?
Note: I have through this link When to choose checked and unchecked exceptions
EDIT:
While going through the answer #Daemon, he says
'Throwable on the other hand, is extended by Exception, and is therefore a checked exception.'
I have a question : Throwable is extended by Error also, so why not it is Unchecked ?
Anything that extends Exception but does not extend RuntimeException. Error and Throwable should not be used by Java programs, as Error is intended to communicate serious, unrecoverable problems such as completely running out of memory, hardware problems, or the like.
Technically, only classes that extend Exception are exceptions; Errors and other Throwables are not exceptions and are not expected to be caught by regular programs.
You are correct that any class extending Exception will be a checked exception, however you are mistaken with your next statement:
If I create a class by extending Throwable,RuntimeException, or Error, then it will be unchecked Exception
If you extend RuntimeException or Error, your class will be a unchecked exception.
Throwable on the other hand, is extended by Exception, and like Exception is a checked exception.
The below code demonstrates these practically. For more information, Barry Ruzek's "Effective Java Exceptions" makes for some very interesting reading on the subject.
public class JavaExceptions {
public static void throwException() throws Exception {
throw new Exception("This is a Checked Exception.");
}
public static void throwRuntimeException() throws RuntimeException {
throw new RuntimeException("This is a Runtime Exception.");
}
public static void throwError() throws Error {
throw new Error("This is an Error.");
}
public static void throwThrowable() throws Throwable {
throw new Throwable("This is a Throwable.");
}
public static void main (String... args) {
//Exception extends Throwable, thus both are checked Exceptions.
try {
throwThrowable();
throwException();
} catch (Throwable e) {
//Handle exception (or throwable in this case)...
e.printStackTrace();
}
//RuntimeException and Error are both unchecked exceptions.
throwRuntimeException();
throwError();
}
}
EDIT 1: In regards to Error and its use, this is taken from Oracle's Documentation:
An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions. The ThreadDeath error, though a "normal" condition, is also a subclass of Error because most applications should not try to catch it.
A method is not required to declare in its throws clause any subclasses of Error that might be thrown during the execution of the method but not caught, since these errors are abnormal conditions that should never occur. That is, Error and its subclasses are regarded as unchecked exceptions for the purposes of compile-time checking of exceptions.
EDIT 2: The classes we are dealing with here can be described as follows:
Throwable extends Object: Top-level class that should be extended by any class that needs to be thrown (like Exceptions and Errors). Throwables are checked. See: Throwable (Java Platform SE 7)
Error extends Throwable: A subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Overides Throwable functionality to become unchecked. See: Error (Java Platform SE 7)
Exception extends Throwable: Another subclass of Throwable that indicate conditions that a reasonable application might want to catch. Like Throwable, is checked. See: Exception (Java Platform SE 7)
RuntimeException extends Exception: The superclass of those exceptions that can be thrown during the normal operation of the Java Virtual Machine. Overrides Exception functionality to become unchecked. See: RuntimeException (Java Platform SE 7)
From the oracle documentation: "For the purposes of compile-time checking of exceptions, Throwable and any subclass of Throwable that is not also a subclass of either RuntimeException or Error are regarded as checked exceptions. " So, your first statement is correct, the second is not.
You can read more in the SCJP Sun Certified Programmer for Java 6 pg. 356-380.
If I create a class by extending Exception class then it will be
checked exception
This is Correct.
If I create a class by extending Throwable,RuntimeException, or Error,
then it will be unchecked Exception
This is incorrect. The class RuntimeException and its subclasses, and the class Error and its subclasses are unchecked exceptions classes. Because the compiler doesn’t forces them to be declared in the throws clause. All the other exception classes that are part of Throwable hierarchy are checked exceptions.
Exception class and Error class both extends Throwable class. RuntimeException class extends Exception class. Checked exceptions should be handles using try catch or throws in compile time. No need for that handling for RunTimeExceptions. Errors should not be handled but let them occur cause they are serious things.

Java exception not caught

Why are some exceptions in Java not caught by catch (Exception ex)? This is code is completely failing out with an unhandled exception. (Java Version 1.4).
public static void main(String[] args) {
try {
//Code ...
} catch (Exception ex) {
System.err.println("Caught Exception");
ex.printStackTrace();
exitCode = app.FAILURE_EXIT_CODE;
}
finally {
app.shutdown();
}
System.exit(exitCode);
}
I get a Exception in thread "main" java.lang.NoSuchMethodError
But this works
public static void main(String[] args) {
int exitCode = app.SUCCESS_EXIT_CODE;
try {
//Code ...
} catch (java.lang.NoSuchMethodError mex){
System.err.println("Caught NoSuchMethodError");
mex.printStackTrace();
exitCode = app.FAILURE_EXIT_CODE;
} catch (Exception ex) {
System.err.println("Caught Exception");
ex.printStackTrace();
exitCode = app.FAILURE_EXIT_CODE;
}
finally {
app.shutdown();
}
System.exit(exitCode);
}
I get Caught NoSuchMethodError java.lang.NoSuchMethodError:
I thought catching exceptions would catch all exceptions? How can I catch all exceptions in java?
Because some exceptions don't derive from Exception - e.g. Throwable and Error.
Basically the type hierarchy is:
Object
|
Throwable
/ \
Exception Error
Only Throwables and derived classes can be thrown, so if you catch Throwable, that really will catch everything.
Throwable, Exception and any exception deriving from Exception other than those derived from RuntimeException count as checked exceptions - they're the ones that you have to declare you'll throw, or catch if you call something that throws them.
All told, the Java exception hierarchy is a bit of a mess...
Errors aren't Exceptions.
The class Exception and its subclasses
are a form of Throwable that indicates
conditions that a reasonable
application might want to catch.
-- JavaDoc for java.lang.Exception
An Error is a subclass of Throwable
that indicates serious problems that a
reasonable application should not try
to catch.
-- JavaDoc for java.lang.Error
There are certain errors that you may want to catch, such as ThreadDeath. ThreadDeath is classified as an Error, as explained below
The class ThreadDeath is specifically
a subclass of Error rather than
Exception, even though it is a "normal
occurrence", because many applications
catch all occurrences of Exception and
then discard the exception.
-- JavaDoc for ThreadDeath
However, since Thread's stop() method is now deprecated, you should not use it, and thus you should never see ThreadDeath.
Exception is just one kind of Throwable; NoSuchMethodError is not an Exception, but an Error, which is another kind of Throwable.
You can catch Throwable. Error and Exception extend Throwable.
see the Throwable JavaDoc:
The Throwable class is the superclass of all errors and exceptions in the Java language.
As other posters have pointed out, not all throwable objects are subclasses of Exception. However, in most circumstances, it is not a good idea to catch Error or Throwable, because these conditions include some really serious error conditions that cannot easily be recovered from. Your recovery code may just make things worse.
First let's clear up some unfortunate semantic confusion in this discussion. There is the java.lang.Exception class which we can refer to simply as Exception with a capital 'E'. Then you have exception with a lowercase 'e' which is a language feature. You can see the lower case version in the documentation for the Throwable class:
For the purposes of compile-time checking of exceptions, Throwable and
any subclass of Throwable that is not also a subclass of either
RuntimeException or Error are regarded as checked exceptions.
For me it's easier to think about the answer to this question as checked vs. unchecked exceptions (lower case e). Checked exceptions must be considered at compile time, whereas unchecked exceptions are not. Exception (uppercase E) and it's subclasses are checked exceptions, which means you either have to catch any exception that can be thrown by your code, or declare the exceptions that your method could throw (if not caught).
Error and it's subclasses are unchecked exceptions, which means your code neither has to catch an Errors that could be thrown, nor do you have to declare that you throw those Errors. RunTimeException and its subclasses are also unchecked exceptions, despite their location in the class hierarchy.
Consider the following code:
void test() {
int a = 1, b = 0, c = a / b;
}
When run, the above code will produce a java.lang.ArithmeticException. This will compile without any errors, even though an exception is thrown and the code neither catches the ArithmeticException nor declares that it throws this exception. This is the essence of unchecked exceptions.
Consider the location of ArithmeticException in the class hierarchy, especially the fact that this is a subclass of java.lang.Exception. Here you have an exception that derives from java.lang.Exception but because it's also a subclass of java.lang.RuntimeException, it's an unchecked exception so you don't have to catch it.
java.lang.Object
java.lang.Throwable
java.lang.Exception
java.lang.RuntimeException
java.lang.ArithmeticException
If you want to catch anything that could possibly be thrown, catch a Throwable. However this may not be the safest thing to do because some of those Throwables could be fatal runtime conditions that perhaps should not be caught. Or if you do catch Throwable, you may want to re-throw Throwables that you can't deal with. It depends on the context.
As both other posts point out, catch(Exception e) will only work for exceptions that derive from Exception. However, if you look at the tree hierarchy, you'll notice that an Exception if Throwable. Throwable also is the base class for Error as well. So, in the case of NoSuchMethodError, it is an Error and not an Exception. Notice the naming convention *Error vs. *Exception (as in IOException, for example).

Categories