Exception declaration in inheritance? - java

package com.rnd.core.java;
import java.io.IOException;
public class TestExceptionInheritance {
public void checkExcpetions () throws ArrayIndexOutOfBoundsException{
System.out.println("Inside TestExceptionInheritance ParentClass");
throw new ArrayIndexOutOfBoundsException();
}
}
package com.rnd.core.java;
import javax.sound.midi.MidiUnavailableException;
public class TestExceptionInheritance2 extends TestExceptionInheritance {
public void checkException () throws MidiUnavailableException {
System.out.println("Hello");
throw new MidiUnavailableException();
}
#Override
public void checkExcpetions() throws StringIndexOutOfBoundsException {
// TODO Auto-generated method stub
//super.checkExcpetions();
System.out.println("HI");
}
public static void main(String[] args) throws Exception {
TestExceptionInheritance obj = new TestExceptionInheritance2();
obj.checkExcpetions();
}
}
I have overriden the checkException Method of the parent class in my subclass but I throw a different exception here.
I want to understand why the compiler allows me to throw an altogether different exception; though I know that the method version would be decided based on the reference type.
-------------------Edit 1---------------------------
I have added an #override notation over the overridden method. Overridden method allows me to throw StringIndexOutOfBoundException and RunTimeException along with ArrayIndexOutOfBoundException but not any other exception like for example Exception.
According to the Exception class hierarchy, both StringIndexOutOfBoundException and ArrayIndexOutOfBoundException are subclasses of IndexOutOfBoundException.
How and why does the compiler allows me to throw StringIndexOutOfBoundException because ArrayIndexOutOfBoundException will be never be caught in StringIndexOutOfBoundException.
Thanks for your help.

The real simple answer is you are not overriding what you think you are. The parent class declares a function public void checkExcpetions () and you have a function public void checkException (). These are two different functions which is why there is no compiler error
Using the #Override tag is one way to have the compiler check that you are overriding what you think you are. In this case if you used the tag there would be an error since you are not overriding a parent method

Related

Java 8 - throw multiple generic checked exceptions in lambda

In a project I am working at, I have found a class which wraps all methods of its super-class in some elaborate exception handling. It looks similar to that:
public void method1() throws ExceptionA {
String exceptionString = "";
try {
super.method1();
} catch (ExceptionA e) {
exceptionString = // <convert the exception to string in an elaborate way>
throw e;
} finally {
// <an elaborate logger call which uses value of exceptionString>
}
}
public void method2() throws ExceptionB, ExceptionC {
String exceptionString = "";
try {
super.method2();
} catch (ExceptionB | ExceptionC e) {
exceptionString = // <convert the exception to string in elaborate way>
throw e;
} finally {
// <an elaborate logger call which uses value of exceptionString>
}
}
// ... <a bunch of other methods like this>
I immediately though "Wow, how could would it be to have one generic wrapper and just call it in every of these methods. The class would be like 10x shorter!".
So I got to work.
This is where I got stuck:
private interface ThrowingMethod<E extends Exception> {
void run() throws E;
}
public <E extends Exception> void wrapMethod(ThrowingMethod<E> method) throws E {
String exceptionString = "";
try {
method.run();
} catch (Exception e) {
exceptionString = // <convert the exception to string in an elaborate way>
throw e;
} finally {
// <an elaborate logger call which uses value of exceptionString>
}
}
public void method1() throws ExceptionA {
wrapMethod(super::method1); // works
}
public void method2() throws ExceptionB, ExceptionC {
wrapMethod(super::method2); // Error in Eclipse: "Unhandled exception type Exception"
}
// ... <a bunch of other methods like this>
In conclusion, this approach works for methods that throws only one type of checked exception. When method throws multiple checked exceptions, Java assumes that the exception type is Exception.
I tried to add more generic parameters to ThrowingMethod and wrapMethod but it doesn't change anything.
How can I get a functional interface to work with multiple generic exceptions?
When you expand your interface to use two type variables, i.e.
private static interface ThrowingMethod<E1 extends Exception,E2 extends Exception> {
void run() throws E1, E2;
}
public <E1 extends Exception,E2 extends Exception>
void wrapMethod(ThrowingMethod<E1,E2> method) throws E1,E2 {
// same as before
}
the rules regarding the type inference do not change and they are the same for both type variables. E.g. you can still use
public void method1() throws ExceptionA {
wrapMethod(super::method1);
}
as before, as the compiler simply infers the same single exception type for both type variables.
For the method declaring two exceptions, it won’t pick up one for the first type variable and the other for the second; there is no rule which could tell the compiler which exception to use for which type variable.
But you can help the compiler out in this case, e.g.
public void method2() throws ExceptionB, ExceptionC {
wrapMethod((ThrowingMethod<ExceptionB, ExceptionC>)super::method2);
}
which is the best you can get with this approach.
So your goal is just to wrap a bunch of methods with logging? A typical way to handle this is with AOP. You'd just create a single pointcut that matches all those methods, and you wouldn't have a bunch of repeated boilerplate. No need for those interfaces or wrapping methods.

Java: testing for the throwing of checked exceptions

I'm trying to figure out a way to build a method that will test whether a checked exception has indeed been thrown. As I was building the following minimal working example (CustomThrowablexxx are all custom types declared on their own files for readability):
package demos.exceptions;
public class TestExceptions {
// This method will check whether the provided method throws exceptions
// of the type provided.
private static boolean throwsParticularThrowable(Runnable method,
Class<Throwable> cls){
try {
method.run();
} catch(Throwable t){
if(t.getClass().equals(cls))
return true;
}
return false;
}
private static void methodOne() throws CustomThrowableOne {
throw new CustomThrowableOne("methodOne() throws");
}
private static void methodTwo() throws CustomThrowableTwo {
throw new CustomThrowableTwo("methodTwo() throws");
}
private static void methodThree() throws CustomThrowableThree {
throw new CustomThrowableThree("methodThree() throws");
}
public static void main(String[] args){
if(!throwsParticularThrowable(TestExceptions::methodOne,
CustomThrowableOne.class))
System.out.println("Nope!");
}
}
I unfortunately noticed that the access to TestExceptions::methodOne was not safe, because the compiler complained that I'm not checking for the throwing of methodOne, which I guess makes sense.
Is there any way I can automate this instead of copying and pasting the code inside throwsParticularThrowable every time?
I don't know what you are looking for but it's easier to test if exceptions are thrown using JUnit ExpectedException
https://junit.org/junit4/javadoc/4.12/org/junit/rules/ExpectedException.html

Java method signature throwing same exception (via generics) twice

Case simplified:
Legacy code. 3 exceptions X,Y and ZException. Class A has method public C fetch(...) throws X and YException and class B has public C fetch(...) throws ZException. The method implementation is almost the same, so I was wondering could I refactor it to some helper class. Method signatures cannot be changed. I came up with the following helper class
public class Common<T extends Exception, V extends Exception>{
public static interface ExceptionSupplier<T extends Exception> {
public T create();
}
private ExceptionSupplier<T> es;
private ExceptionSupplier<V> es2;
public Common(ExceptionSupplier<T> es, ExceptionSupplier<V> es2) {
this.es = es;
this.es2 = es2;
}
public void method() throws T, V {
//example that would could throw both T and V
if (Math.random() < 0.5) {
throw es.create();
} else {
throw es2.create();
}
}
}
Then I can create instance of that Common class in A and B e.g.
helper = new CommonThrower<ZException, ZException>(zSupplier, zSupplier);
helper = new CommonThrower<XException, YException>(xSupplier, ySupplier)
and call helper.fetch(...) and it shows (in eclipse) beging throw correct types. However it will (as somewhat expected) throwing ZException twice.
My question is there any problem having a method signature throws SomeException, SomeException (i.e. declaring the same exception again)? The code compiles and runs fine.
... throws IOException, IOException { ... .
Redundancy is just confusing, but runs fine.
A more common example of redundancy is something like
throws StreamCorruptedException, IOException {
In this case StreamCorruptedException is an IOException so it is not needed, but might be included to make it consistent with the Javadoc which might give more details for this exception.

Java -- thrown exceptions in implemented/overridden methods [duplicate]

The code below gives a checked error to throws Exception:
import java.io.IOException;
interface some {
void ss99() throws IOException;
}
public class SQL2 implements some {
#Override
public void ss99 () throws Exception {}
// ...
}
while the one below compiles fine:
import java.io.IOException;
interface some {
void ss99() throws IOException;
}
public class SQL2 implements some {
#Override
public void ss99 () throws NullPointerException {}
// ...
}
On what logic is Java doing this-- any ideas?
TIA.
The throws keyword indicates that a method or constructor can throw an exception, although it doesn't have to.
Let's start with your second snippet
interface some {
void ss99() throws IOException;
}
public class SQL2 implements some {
#Override
public void ss99 () throws NullPointerException {}
}
Consider
some ref = getSome();
try {
ref.ss99();
} catch (IOException e) {
// handle
}
All you have to work with is with your interface some. We (the compiler) don't know the actual implementation of the object it is referencing. As such, we have to make sure to handle any IOException that may be thrown.
In the case of
SQL2 ref = new SQL2();
ref.ss99();
you're working with the actual implementation. This implementation guarantees that it will never throw an IOException (by not declaring it). You therefore don't have to deal with it. You also don't have to deal with NullPointerException because it is an unchecked exception.
Regarding your first snippet, slightly changed
interface some {
void ss99() throws IOException;
}
public class SQL2 implements some {
#Override
public void ss99 () throws Exception { throw new SQLException(); }
}
Consider
some ref = new SQL2();
try {
ref.ss99();
} catch (IOException e) {
// handle
}
So although you are handling the exception declared in the interface, you would be letting a checked exception, SQLException, escape unhandled. The compiler cannot allow this.
An overriden method must be declared to throw the same exception (as the parent) or one of its subclasses.

exception handling in the implemented method

The code below gives a checked error to throws Exception:
import java.io.IOException;
interface some {
void ss99() throws IOException;
}
public class SQL2 implements some {
#Override
public void ss99 () throws Exception {}
// ...
}
while the one below compiles fine:
import java.io.IOException;
interface some {
void ss99() throws IOException;
}
public class SQL2 implements some {
#Override
public void ss99 () throws NullPointerException {}
// ...
}
On what logic is Java doing this-- any ideas?
TIA.
The throws keyword indicates that a method or constructor can throw an exception, although it doesn't have to.
Let's start with your second snippet
interface some {
void ss99() throws IOException;
}
public class SQL2 implements some {
#Override
public void ss99 () throws NullPointerException {}
}
Consider
some ref = getSome();
try {
ref.ss99();
} catch (IOException e) {
// handle
}
All you have to work with is with your interface some. We (the compiler) don't know the actual implementation of the object it is referencing. As such, we have to make sure to handle any IOException that may be thrown.
In the case of
SQL2 ref = new SQL2();
ref.ss99();
you're working with the actual implementation. This implementation guarantees that it will never throw an IOException (by not declaring it). You therefore don't have to deal with it. You also don't have to deal with NullPointerException because it is an unchecked exception.
Regarding your first snippet, slightly changed
interface some {
void ss99() throws IOException;
}
public class SQL2 implements some {
#Override
public void ss99 () throws Exception { throw new SQLException(); }
}
Consider
some ref = new SQL2();
try {
ref.ss99();
} catch (IOException e) {
// handle
}
So although you are handling the exception declared in the interface, you would be letting a checked exception, SQLException, escape unhandled. The compiler cannot allow this.
An overriden method must be declared to throw the same exception (as the parent) or one of its subclasses.

Categories

Resources