catching java.lang.ArrayIndexOutOfBoundsException - java

I'm new in Java. Can anyone help me with explanation, why the catch is not catching the MyException (which extends ArrayIndexOutOfBoundsException)?
My example:
public class TestClass {
public static void main(String[] args) {
try{
doTest();
}
catch(MyException me){
System.out.println("MyException is here");
}
}
static void doTest() throws MyException{
int[] array = new int[10];
array[10] = 1000;
}
}
class MyException extends ArrayIndexOutOfBoundsException {
public MyException(String msg){
super(msg);
}
}
The result is:
"Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10         at TestClass.doTest(TestClass.java:14)         at TestClass.main(TestClass.java:5)"
Why is not "MyException is here"?

Your method actually throws only ArrayIndexOutOfBoundsException.
You catch MyException but that is not what is being thrown, so the catch clause has no effect.
If you wanted to throw MyException you would have to modify the method to catch ArrayIndexOutOfBoundsException and throw MyException instead.

You are confusing the subtype-supertype-relationship.
The code as it is throws an ArrayIndexOutOfBoundsException but not a MyException. Catching the latter will not work because an AIOOBE is not a ME. Your ME is a subtype of AIOOBE.
On the other hand, an AIOOBE has a supertype: IndexOutOfBoundsException. If you have a catch clause for this one, you will get the desired behavior because an AIOOBE is a IOOBE.
Or you could simply throw your ME yourself: throw new MyException(...)

Your doTest method does not throw your custom exception. To throw an exception use
throw new MyException("your message");

Related

Why User defined Exception not throws over Generic Exception?

I have created below User Defined Exception (MyException) class which extends Exception, Now I manually try to create a NullPointerException, But instead of throwing (MyException), it throws the same Generic(NullPointerException) Exception
public class Sample {
public static void main(String[] args) throws MyException {
String a = null;
callMethod(a);
}
public static void callMethod(String a) throws MyException {
a.toString();
}
}
public class MyException extends Exception {
public MyException(String exception)
{
super(exception);
}
}
Below is the Exception I'm getting
Exception in thread "main" java.lang.NullPointerException
at Sample.callMethod(Sample.java:9)
at Sample.main(Sample.java:5)
Process finished with exit code 1
The fact that you declare that a method throws an exception does not mean it will throw that exception when any other exception is thrown in the code.
In this case, a is null so the exception that's thrown is a NullPointerException. If you wanted to throw your custom exception you would have to check whether your value is null and throw your custom exception, like this
public static void callMethod(String a) throws MyException {
if (a == null) {
throw new MyException(e);
}
a.toString();
}
Declaring that a method throws MyException means that it may throw that exception.
It does not mean that all thrown exceptions automatically get wrapped in your MyException
Using throws MyException does mean that the method can throw an exception and u need to handle it, but it doesn't mean every exception u get inside the method will be thrown as MyException. If u want to throw every Exception u get as MyException you can do :
public static void main(String[] args) throws MyException {
try{
String a = null;
callMethod(a);
}catch(Exception e){
throw new MyException(...);
}
}

How to handle a runtime error with throws

In the following code snippet, there are cases where the processes cannot handle NullPointerException and IllegalStateException. Namely in the case where I have the input values val=-4 or val=-2.
I read that adding throws after methods' signatures would help. But the code still aborts if I pass the mentioned values over.
public class Test extends Throwable{
public static void processA(int val ) throws NullPointerException, IllegalStateException{
try{
System.out.println("1");
processB(val);
}catch(ArithmeticException e){
System.out.println("2");
}
System.out.println("3");
}
public static void processB(int val) throws NullPointerException, IllegalStateException{
try{
System.out.println("4");
processC(val);
}catch(NullPointerException e){
System.out.println("5");
processC(val+4);
}finally{
System.out.println("6");
}
System.out.println("7");
}
public static void processC(int val)throws NullPointerException, IllegalStateException, ArithmeticException{
System.out.println("8");
if(val<1) throw new NullPointerException();
if(val==1) throw new ArithmeticException();
if(val>1) throw new IllegalStateException();
System.out.println("9");
}
public static void main(String[] args) throws Exception {
processA(1); //processA(-2) or processA(-4)
}
}
It breaks because you are not handling the scenario when a NullPointerException or IllegalStateException is thrown to processA(...). You only handle an ArithmeticException.
Add the following to your code, thereby if any of the three exceptions are thrown, it is handled by method processA.
public static void processA(int val) throws NullPointerException, IllegalStateException {
try {
System.out.println("1");
processB(val);
} catch (ArithmeticException e) {
System.out.println("11");
} catch (NullPointerException e) {
System.out.println("12");
} catch (IllegalStateException e) {
System.out.println("13");
}
System.out.println("3");
}
If you want the caller to handle them then you need to do the same from the caller method. For eg :
public static void main(String[] args) {
try {
processA(12);
} catch (ArithmeticException | NullPointerException | IllegalStateException e) {
// do something here
}
}
To answer your question in the comments: "But why should I use it?"
This will indicate that the caller will need to handle the exception thrown by that method. Now the caller can handle it via a try-catch block or it can re-throw the exception to its caller. The compiler would also give you an error saying that the exception should be handled but this would happen only for checked exceptions. The ones you are throwing are unchecked exceptions. Which means in your case you can pretty much ignore them from the method declaration.
I would suggest you also consider using Thread.UncaughtExceptionHandler in order to make sure you properly handle exceptions which were not properly caught.
Missing out on exception handling is a very common occurrence and can be easily avoided using this API.
References:
How to catch an exception from a thread
Oracle official API
UncaughtExceptionHandler as a best practice

tips "Unhandled exception type xxx" in eclipse

I don't think I understand the try-catch block and throws really.
public class TestException {
public static void main(String[] args) {
new TestException().tt();
}
public void tt() {
try {
throw new RuntimeException();
}catch (Exception e) {
throw e;
}
}
}
When in Eclipse, there is an error hint about 'Unhandled exception type xxx', and if you run this, you will get an
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Unhandled exception type Exception
But in Idea, there's no errors. It runs and throws the exception correctly.
In my opnion, the 'e' was not declared as a RuntimeException(althrough it is an RuntimeException), so the tt() method must be declared with throws. But actually it's not. Why?
This should answer your question:
public class TestException {
public static void main(String[] args) {
new TestException().tt();
}
public void tt() {
try {
throw new RuntimeException();
}catch (Exception e) {
throw new RuntimeException(e);
}
}
}
If you use throws, you tell those who use your function, "My function may throw exceptions. You have to handle that."
You should get difference of throws and throw in this sentence.
If you use try-catch, you handle that exception.
1) You should add throws keyword like below
public class TestException {
public static void main(String[] args) {
new TestException().tt();
}
public void tt() **throws Exception** {
try {
throw new RuntimeException();
}catch (Exception e) {
throw e;
}
}
}
2) Handle exception where you use function
public class TestException {
public static void main(String[] args) {
try{
new TestException().tt();
}catch(Exception e){
System.out.println("Error handled");
}
}
public void tt() throws Exception {
try {
throw new RuntimeException();
}catch (Exception e) {
throw e;
}
}
}
In general if you catch an exception you handle it. Like this
public class TestException {
public static void main(String[] args) {
new TestException().tt();
}
public void tt() {
try {
throw new RuntimeException();
}catch (Exception e) {
System.out.println("Error caught! ")
}
}
}
or
public class TestException {
public static void main(String[] args) {
try {
new TestException().tt();
}catch(Exception e){
System.out.println("Error caught! ")
}
}
public void tt() throws RuntimeException {
throw new RuntimeException();
}
}
You can also throw other's exception
public class TestException {
public static void main(String[] args) {
try{
new TestException().a();
}catch(Exception e){
System.out.println("Error handled");
}
}
public void a() throws Exception {
b();
}
public void b() throws Exception {
c();
}
public void c() throws Exception {
throw new RuntimeException();
}
}
I think that you want to look into 'Checked Exceptions' and 'Unchecked Exceptions'.
Only Checked Exceptions need to be declared in a methods signature, and RuntimeException is an unchecked exception (though you can declare it if you like - it just isn't necessary to compile).
https://docs.oracle.com/javase/7/docs/api/java/lang/Exception.html
The API for java Exception says:
"The class Exception and any subclasses that are not also subclasses of RuntimeException are checked exceptions. Checked exceptions need to be declared in a method or constructor's throws clause if they can be thrown by the execution of the method or constructor and propagate outside the method or constructor boundary"
https://docs.oracle.com/javase/7/docs/api/java/lang/RuntimeException.html
The API for java RuntimeException says:
"RuntimeException and its subclasses are unchecked exceptions. Unchecked exceptions do not need to be declared in a method or constructor's throws clause if they can be thrown by the execution of the method or constructor and propagate outside the method or constructor boundary."
In my opnion, the 'e' was not declared as a RuntimeException(althrough it is an RuntimeException), so the tt() method must be declared with throws. But actually it's not. Why?
Let's consider what we know:
When using rethrow syntax, the existing exception object (e) is rethrown.
e is an object of class Exception, or one of its subtypes.
RuntimeException is a subtype of exception, and is not compiled time checked, so it's possible the re-thrown object is a non compile time checked object.
The compiler cannot see a place where the code definitely, or even possibly throws a compile checked exception, and so it makes sense that it does not force those semantics.
For example, if you change your catch to an IOException, the compiler will not allow you to do that without a line in the try which could possibly lead to an IOException.
If you added such a line, then the compiler would recognize that the throw would rethrow a compile time checked exception, and make you catch it again, or mark the function with the appropriate throws clause.
As for eclipse, your code compiles OK in mine with my JDK.

Handling Checked and unchecked exceptions?

I have below class with one method which throws Checked Exception.
public class Sample{
public String getName() throws CustomException{
//Some code
//this method contacts some third party library and that can throw RunTimeExceptions
}
}
CustomException.java
public class CustomException Extends Exception{
//Some code
}
Now in another class i need to call above the method and handle exceptions.
public String getResult() throws Exception{
try{
String result = sample.getName();
//some code
}catch(){
//here i need to handle exceptions
}
return result;
}
My requirement is:
sample.getName() can throw CustomException and it can also throw RunTimeExceptions.
In the catch block, I need to catch the exception. If the exception that is caught is RunTimeException then I need to check if the RunTimeException is an instance of SomeOtherRunTimeException. If so, I should throw null instead.
If RunTimeException is not an instance of SomeOtherRunTimeException then I simply need to rethrow the same run time exception.
If the caught exception is a CustomException or any other Checked Exception, then I need to rethrow the same. How can I do that?
You can do like this :
catch(RuntimeException r)
{
if(r instanceof SomeRunTimeException)
throw null;
else throw r;
}
catch(Exception e)
{
throw e;
}
Note: Exception catches all the exceptions. That's why it is placed at the bottom.
You can simply do:
public String getResult() throws Exception {
String result = sample.getName(); // move this out of the try catch
try {
// some code
} catch (SomeOtherRunTimeException e) {
return null;
}
return result;
}
All other checked and unchecked exceptions will be propagated. There is no need to catch and rethrow.

How does the correct rethrow code look like for this example

Yesterday I red this article about the new Exception Handling in Java 7.
In the article they show an example (No 4) which is not working in Java 6. I just copied it.
public class ExampleExceptionRethrowInvalid {
public static void demoRethrow()throws IOException {
try {
// forcing an IOException here as an example,
// normally some code could trigger this.
throw new IOException("Error");
}
catch(Exception exception) {
/*
* Do some handling and then rethrow.
*/
throw exception;
}
}
public static void main( String[] args )
{
try {
demoRethrow();
}
catch(IOException exception) {
System.err.println(exception.getMessage());
}
}
}
Like in the article descriped it won't compile, because of the type missmatch -throws IOException- and -throw exception-. In Java 7 it will. So my question is.
How do I proper implement this kind of rethrowing of an exception in Java 6? I don't like the suggested implementation example no five. I know it is a matter of taste and problem you try to handle if unchecked exceptions or not. So what can I do to get the -throws IOException- and keep the stack trace? Should I only change the catch to IOException and risk not catching all?
I'm curious about your answers.
Simply catch IOException, like so:
public static void demoRethrow()throws IOException {
try {
// forcing an IOException here as an example,
// normally some code could trigger this.
throw new IOException("Error");
}
catch(IOException exception) {
/*
* Do some handling and then rethrow.
*/
throw exception;
}
}
If the code inside the try block can throw a checked exception other than IOException, the compiler will flag this up as an error, so you're not "risk[ing] not catching all".
If you're also interested in unchecked exceptions, you could also catch and re-throw RuntimeException (you won't need to declare it in the throws clause).
Catch IOException and everything else separately:
public static void demoRethrow() throws IOException {
try {
throw new IOException("Error");
}
catch(IOException exception) {
throw exception;
}
catch(Exception exception) {
throw new IOException(exception);
}
catch(Exception ex) catches both checked and unchecked (RuntimeException) exceptions.
So to make it functionaly equivalent,
public static void demoRethrow() throws IOException {
try {
throw new IOException("Error");
}
catch(IOException exception) {
throw exception;
}
catch(RuntimeException exception) {
throw new IOException(exception);
}
suffice, and compiler will detect other checked exceptions (good for thinking again about whether they should realy get this far, or should have bean delt with before)
A hacky way to throw to catch a generic exception and rethrow without the compiler checking the exception is to use stop.
public static void demoRethrow() throws IOException {
try {
throw new IOException("Error");
} catch(Throwable t) {
// handle exception
// rethrow the exception without compiler checks.
Thread.currentThread().stop(t);
}
}

Categories