When you see public static <T, E extends Exception> T call(Class<E> exceptionClass, SQLExceptionThrowingFunction<Connection, T, E> f) throws E , which reports:
- type
E in Class<E> (your first argument, exceptionClass) and - type
E in SQLExceptionThrowingFunction<Connection, T, E> f) throws E
must be of the same type / subtype.
Therefore, it is expected that E (i.e. SQLException ) in SQLExceptionThrowingFunction will have a subtype of E (exceptionClass), which is passed as a RuntimeException ). (this happens when you call ConnectionPool.call(RuntimeException.class, Test::<SQLException>mayThrow1);
Since this wait fails, you get a compilation error.
You can verify this by changing ...
ConnectionPool.call(RuntimeException.class, Test::<SQLException>mayThrow1); toConnectionPool.call( .class, fitest.Test::<SQLException>mayThrow1); exception .class, fitest.Test::<SQLException>mayThrow1); which will remove the error on this line.
Not sure if this is your intention initially.
1: What can you do to use common stuff (if you don't want to throw exceptions, this is the method of calling changes, as shown below, and then all your code will work.
public static <T> T call2(Class exceptionClass, SQLExceptionThrowingFunction<Connection,T, Exception> f) { throw new UnsupportedOperationException("unimportant"); }
2: Or you can just call it without specifying a type. eg
ConnectionPool.call(RuntimeException.class, Test::mayThrow0); ConnectionPool.call(Checked.class, Test::mayThrow1);
I am not sure if this solves your question. If you have a different intention when you said Is there a way to get this to work, or is the workaround of specifying the type arguments the only way that you really wanted, then please share the pseduo syntax, as if you wanted the material to work.