I think an enum declaration is 'morally final' in the sense that, while
it can't really be marked with ACC_FINAL (because there might be
constants which extend from it), the user cannot subclass the enum.
Everything weird you can do with an enum, remains _inside_ the enum
declaration bubble, which I think makes mixing enums and sealed
interface pretty safe. It is also lucky that we can't say 'final enum' -
meaning that I would also extend it to the other keywords - that is, you
can't put sealed, non-sealed on an enum.
Regarding the 'anonymous enum constant' issue you raise how is that
different from:
sealed interface Y permits Bar, Baz {}
class Bar implements Y {}
... new Bar() {}
In this case, I don't think you break exhaustiveness in the same way you
do if you allow anonymous implementations of Y.
Clients will be assuming that Y is either a Bar or a Baz, and the fact
that some of the Bars are anonymous instance is immaterial to this.
Unless I misunderstood what you were trying to say. If not, I think my
reasoning here would be to:
1) allow enums to implement sealed interfaces
1b) do not allow sealed, non-sealed modifiers on an enum (e.g. do the
same as with final)
2) allow anonymous enum constants inside the enums in (1) - as they
can't break exhaustiveness for clients
Maurizio
On 11/10/2019 04:02, Tagir Valeev wrote:
Hello!
Sorry if this was already discussed, but what about enums extending
sealed interfaces? E.g.:
sealed interface X permits Foo {}
enum Foo implements X { // can we do this?
A {}, // and what about this? Here we have an additional subclass at
runtime. Or we should explicitly declare "non-sealed enum Foo" to
allow this?
B,
C
}
With best regards,
Tagir Valeev.
On Thu, Oct 10, 2019 at 3:46 PM Maurizio Cimadamore
<maurizio.cimadam...@oracle.com> wrote:
On 10/10/2019 01:50, Brian Goetz wrote:
Right. We already restrict anon and lambda instances of the sealed
type. Not only can't we stably write down their types in the PS
attribute, but even if we could, it's so easy to accidentally lose
exhaustiveness.
This is a very good point; if I have type T = A | B | C, but then I have
'anonymous' Ts flying around, all switches assuming A|B|C are no longer
exhaustive.
Maurizio