<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<font size="4"><font face="monospace">First question: what is the
type of `e` in your catch block? <br>
<br>
You might think it is the union type MyAbstractException |
MyUncheckedException, but in fact it is the least upper bound
(LUB) of the two, which turns out to be RuntimeException, as per
JLS 14.20:<br>
<br>
<blockquote type="cite">The declared type of an exception
parameter that denotes its type as a union with<br>
alternatives D1 | D2 | ... | Dn is lub(D1, D2, ..., Dn).</blockquote>
<br>
So your switch is a switch on a variable of type
RuntimeException, and the switch is obviously not exhaustive.
So the compiler is correct.<br>
<br>
You might ask: why would we define the type of the catch formal
like this? Well, you have to go back to the context in which
multi-catch was added. This was the Project Coin days, where
the scope was very limited -- including no type system changes
-- and the use of LUB in this way was a trade-off that made it
mostly acceptable. The alternative would have been adding
full-blown union types, which would not have been a small change
(see this PhD thesis which outlines what would have been
involved: <a class="moz-txt-link-freetext" href="https://scholarship.rice.edu/handle/1911/103594">https://scholarship.rice.edu/handle/1911/103594</a>). <br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
</font></font><br>
<div class="moz-cite-prefix">On 8/1/2022 8:28 AM, Thiago Henrique
Hupner wrote:<br>
</div>
<blockquote type="cite" cite="mid:CAENv9VFnszfHe7+6_NYq=OEF6YwWkO8Fy8uu9xdOcEKbbcyD+w@mail.gmail.com">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">Hello all!
<div><br>
</div>
<div>I've played around with the exhaustiveness check
and I'd like to</div>
<div>discuss whether the following code should compile
or it is right not to compile.</div>
<div><br>
</div>
<div>
<div>import java.util.*;</div>
<div>import java.io.*;</div>
<div><br>
</div>
<div>sealed abstract class MyAbstractException extends
RuntimeException {</div>
<div> final static class MyException extends
MyAbstractException {}</div>
<div>}</div>
<div><br>
</div>
<div>final class MyUncheckedException extends
UncheckedIOException {</div>
<div> public MyUncheckedException() {</div>
<div> super(null);</div>
<div> }</div>
<div>}</div>
<div><br>
</div>
<div>public class SealedException {</div>
<div> public static void main(String[] args) {</div>
<div> try {</div>
<div> throw new MyUncheckedException();</div>
<div> } catch (MyAbstractException |
MyUncheckedException e) {</div>
<div> switch (e) {</div>
<div> case
MyAbstractException.MyException a -> {}</div>
<div> case MyUncheckedException b ->
{}</div>
<div> }</div>
<div> }</div>
<div> }</div>
<div>}</div>
</div>
<div><br>
</div>
<div>As MyUncheckedExceptionh is final, and
MyAbstractException.MyException is the only
implementation available for MyAbstractException, I
guess it is exhaustive, but the compiler disagrees.</div>
<div><br>
</div>
<div>
<div>SealedException.java:23: error: the switch
statement does not cover all possible input values</div>
<div> switch (e) {</div>
<div> ^</div>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
<br>
</body>
</html>