Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

throwing Generic Exception in java

I have another challenging question from javaDeathMatch game; In the code below we are asked what kind of problem the code below has. please correct me if I am wrong; compilation error : None; At compile time the erasure of type parameter has not still occurred and the dynamic binding has not been taken place, so the parameter passed to the method which is of type SQLException is thought of as Exception in the method 'pleaseThrow' and it(i mean Exception not SQLException) is cast to Runtime Exception in the method with no error. The only error is that we don't have a proper catch clause to catch the exception.

public class Exption<T extends Exception> {
    public static void main(String[] args) {
        try {
            new Exption<RuntimeException>().pleaseThrow(new SQLException());
        }catch (final SQLException ex){
            ex.printStackTrace();
        }
    }
    private void pleaseThrow(final Exception t) throws T{
        throw (T)t;
    }
}

if we replace the catch clause with this:

catch(final RuntimeException e){
    e.printStackTrace();
    System.err.println("caught");
}

the exception will be caught but the System.err.println("caught") will never be printed!!! What is the problem????

like image 358
AlirezaAsadi Avatar asked Sep 03 '25 15:09

AlirezaAsadi


1 Answers

This is due to type erasure. In java after compilation, every generic information is lost (there is something left, which is not relevant to this though). That means that during compilation, the generic variable T is equal to RuntimeException. So your pleaseThrow code looks like this:

private void pleaseThrow(final Exception t) throws RuntimeException{
    throw (RuntimeException)t;
}

After compilation though, every generic parameter is erased to the base type. In your case, to Exception. Which leaves you with a method signature like this:

private void pleaseThrow(final Exception t) throws Exception{
    throw (Exception)t;
}

Which finally is clear, why your catch block is never reached. You're trying to catch RuntimeExceptions but what you're actually throwing is a checked exception. Which then propagates upwards and is finally caught by the JVM.

Additional reading: Oracle Tutorial on type erasure

like image 90
Lino Avatar answered Sep 05 '25 04:09

Lino