Unfortunately, generic Exceptions can neither be caught nor thrown in Java, thus something like ... is not possible.
Change that to:
public void <T extends Exception> retriedOperation(...) throws T { ... }
And it should work just fine. When T is a checked exception, the compiler will complain appropriately. E.g.
obj.<IOException>retriedOperation(...);
Will force the surrounding method to either handle IOException or declare that it throws it. However, as long as Operable specifies that it throws Exception, your code won't work, since the method would have to check if the caught exception is of a particular type it doesn't yet know. The real solution is to change Operable to specify whatever exception it throws:
class Operable<T extends Exception>
And now you can rewrite your method as
public <T extends Exception> void retriedOperation(Operable<T> operable, ...) throws T {
...
} catch (Exception e) {
if (attempt + 1 > maxAttempts) {
throw (T) e;
}
}
...
}
And everything will work just fine, provided Operable only throws one kind of exception. If you need to handle more than one, the solution will get a bit ugly - you'll have to pass a list of class tokens as an argument and check if the caught exception is of a compatible type for any of them.
Finally, it seems to me retriedOperation should be a static method.