-8

Can a Java enum implement a sealed interface in Java and why?

A sealed subclass must be final, sealed or non-sealed. My reasoning is that if an enum could implement a sealed interface it can only be non-sealed, because it cannot be marked final and it cannot be extended either, therefore it cannot be marked sealed.

I’m sorry if there is the answer somwhere but I can’t seem to find it.

Naruga
  • 1
  • 1
  • "*If it would implement a sealed interface it can only be non-sealed.*"—I don't understand what that is intended to mean. – khelwood May 19 '23 at 11:33
  • Why do you think a thing that _implements_ a sealed interface can't be _final_? Link to whatever docs/specs, etc. – rzwitserloot May 19 '23 at 11:34
  • @khelwood Because subtypes of sealed must be final, sealed or non sealed – Naruga May 19 '23 at 11:37
  • @rzwitserloot That’s not what I meant. I said an enum cannot be final. – Naruga May 19 '23 at 11:38
  • @JoachimSauer This is my first time asking a question here. It was generated automatically and I fixed it :) – Naruga May 19 '23 at 11:39
  • @Raed an enum is always final, therefore, you don't need to declare it final – Maurice Perry May 19 '23 at 11:40
  • @MauricePerry I think my reasoning was not that clear. I edited my question – Naruga May 19 '23 at 11:43
  • 1
    That's a tricky argument. The enum type _itself_ isn't final but _is_ 'sealed', in the sense that any subtypes are either right there in the same source file, or cannot exist. I think you're being downvoted because you've done no work at all here. Why haven't you tried it? Show the code, show the compiler output. Why haven't you linked to the relevant sections in the JLS? Is your point 'I think javac and the spec disagree', or is your point 'can I or can't I'? – rzwitserloot May 19 '23 at 11:43
  • 2
    @Naruga The intent of the downvote is to discourage people from asking bad questions. We aren't paid by StackOverflow or otherwise directly benefit from it being used a lot. In fact, quite the opposite: If SO attracts bad questions, I think most folks who frequently answer SO questions would be saddened by that. – rzwitserloot May 19 '23 at 11:51
  • 1
    From Java Language Specification [8.9. Enum Classes](https://docs.oracle.com/javase/specs/jls/se20/html/jls-8.html#jls-8.9-210): "An enum class is either implicitly final or implicitly sealed, ...", that is, "*can only be non-sealed*" is not correct – user16320675 May 19 '23 at 11:59

1 Answers1

4

I have taken the 5 seconds required to test it:

Foo.java:

public sealed interface Foo permits Bar {}

Bar.java:

public enum Bar implements Foo {
  A, B {
    void baz() {}
  }
}

The enum even has effectively a subclass (the inner class representing B).

> javac *.java

compiles just fine, no complaints from javac.

From a mental model it makes perfect sense: An enum type quacks, walks, and swims like a final type: An enum cannot be extended by other code, only by recompiling it. Yes, an enum can be 'subclassed' (that's what B up there is doing: It makes a new anonymous class, more or less named Foo$B extends Foo, which includes that baz() method, and the JVM will make a singleton instance of that class. Except, of course, javac manages all this. You cannot actually get an actual source file with the actual letters class Foo$B extends Foo {} (where Foo is an enum) to be compiled with a javac that adheres to the spec.

It sounds like you were asking 'is it possible', in which case, [A] yes, and [B] I strongly suggest you just try this stuff; it'll take less time than writing an SO question and you learn more.

Perhaps you meant: "I think they should not, but javac allows it". In which case, that breaks down into 2 further variants: "... I am confused about why it is allowed" (the above explanation should then suffice to explain why), or "... I think the JLS is broken because the way I read it, you should not be able to do this". In which case, file a bug with openjdk project, if you want. But the bug is then in the JLS, not in javac: Being able to write the above is obviously the right intent.

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72
  • 1
    Actually, your `enum` type with subclass quacks, walks, and swims like a `sealed` type. The difference between an implicitly final and implicitly sealed enum has [been defined precisely in JLS §8.9](https://docs.oracle.com/javase/specs/jls/se20/html/jls-8.html#jls-8.9:~:text=An%20enum%20class%20is%20either%20implicitly%20final%20or%20implicitly%20sealed%2C%20as,have%20a%20class%20body.) – Holger May 22 '23 at 10:24
  • That's getting into a bit more detail, but, sure. The sealed system doesn't make sense if one of the things explicitly listed is uncontrollably extendable. Both `final` and `sealed` types have the property that they are _not_ infinitely extendable; but given that OP seemed to be somewhat confused about what `sealed` does, I thought it best to stick to simpler concepts. – rzwitserloot May 22 '23 at 12:09
  • 1
    I had the feeling that saying “it’s like final”, followed by having to explain why it still is like final despite having a subclass is more complicated than saying “it’s like sealed” which is a perfect fit, as you said, it’s “not infinitely extendable”. But in the end, I think the OP’s confusion has to do with the wrong assumption that an explicit “final” or “sealed” modifier was needed. Which is then contradicted by the assumption “it can only be non-sealed” despite it’s impossible to add the “non-sealed” modifier either. – Holger May 22 '23 at 12:26