There've been a few times I've used checked exceptions very locally in Java where I did use a type parameter successfully for this—though it's not really threaded through the type signatures in the standard libraries, so interop can be a problem. Almost like what you wrote, of course more verbosely, something like:
interface SomeProcessor {
void process(Thing thing) throws E;
}
void processThingsSomehow(
SomeProcessor processor,
Container things,
Parameter how) throws E {
// ... {
processor.process(extractedThing);
// } ...
}
and then later:
void processOrFail(Thing thing)
throws SomeCheckedException {
// ...
}
void processOurThings() {
try {
someObject.processThingsSomehow(
this::processOrFail,
getThings(), HOW);
} catch (SomeCheckedException e) {
// ...
}
}
and it definitely worked the way I expected—if the correct exceptions weren't caught in processOurThings, it wouldn't compile, and processThingsSomehow did not have to catch them. It even worked in at least some cases with multiple throws on the concrete SomeProcessor, though I think the different exceptions involved had an upper type bound within the package; I don't know how well that's handled in the general case.