Treat it like any other generic code you've read.
Here's the formal signature from what I see in Java 8's source code:
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X
X
has an upper bound of Throwable
. This will be important later on.
- We return a type
T
which is bound to Optional
's T
- We expect a
Supplier
which has a wildcard upper bound of X
- We throw
X
(which is valid, since X
has an upper bound of Throwable
). This is specified in JLS 8.4.6; so long as X
is seen as a subtype of Throwable
, its declaration is valid and legal here.
There is an open bug about the Javadoc being misleading. In this case, it's best to trust the source code as opposed to the documentation until the bug is declared fixed.
As for why we're using throws X
instead of throws Throwable
: X
is guaranteed to be bound to Throwable
in the uppermost bounds. If you want a more specific Throwable
(runtime, checked, or Error
), then merely throwing Throwable
wouldn't give you that flexibility.
To your last question:
Will this method be required to be caught in a catch(Throwable t) clause?
Something down the chain has to handle the exception, be that a try...catch
block or the JVM itself. Ideally, one would want to create a Supplier
bound to an exception that best conveyed their needs. You don't have to (and probably should not) create a catch(Throwable t)
for this case; if your Supplier
is type bound to a specific exception that you need to handle, then it's best to use that as your catch
later up in the chain.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…