Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
326 views
in Technique[技术] by (71.8m points)

java - throws x extends Exception method signature

Reading the JavaDoc of Optional, I bumped in a weird method signature; I never saw in my life:

public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier)
                                throws X extends Throwable

At first glance, I wondered how the generic exception <X extends Throwable> is even possible, since you can't do that (here, and here). On second thought, this starts to make sense, as it is here just to bind the Supplier... but the supplier itself knows exactly what type it should be, before generics.

But the second line hit me:

  • throws X is a complete generic exception type.

And then:

  • X extends Throwable, what in the world does this mean?
    • X is already bound in the method signature.
  • Will this by any means, solve the generic exception restriction?
  • Why not just throws Throwable, as the rest will be erased by type erasure?

And one, not directly related question:

  • Will this method be required to be caught as catch(Throwable t), or by the provided Supplier's type; since it can't be checked for at runtime?
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...