Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can individual values of an enum implement an interface

Tags:

java

enums

An enum can implement an interface. Is it possible for some of the values to implement an interface? The use case that I am thinking of is a tagging interface, so something like the following:

interface Foo {}
interface Bar {}

enum Widgets {
  FOO implements Foo,
  BAR_1 implements Bar,
  BAR_2 implements Bar
}

That does not compile under Java 1.8. I know that internally, there are separate classes created for FOO and BAR_1, so it seems this is possible, but I can easily see the standard not supporting it.

Something similar that should work is

interface Widgets;
enum Foo implements Widgets { FOO };
enum Bar implements Widgets { BAR_1, BAR_2 };

This has the drawback that I cannot just do Widgets.values() and get all of the Widgets.

like image 416
Troy Daniels Avatar asked Feb 09 '23 09:02

Troy Daniels


1 Answers

The Java Language Specification states

The optional class body of an enum constant implicitly defines an anonymous class declaration (§15.9.5) that extends the immediately enclosing enum type. The class body is governed by the usual rules of anonymous classes; in particular it cannot contain any constructors. Instance methods declared in these class bodies may be invoked outside the enclosing enum type only if they override accessible methods in the enclosing enum type (§8.4.8).

An anonymous class can only extend (or implement) the type specified in the new instance creation expression, your enum type in this case. As such, you can't have it additionally implement an interface.


The following

enum Foo {
    CONSTANT
}

gets compiled to something similar to

class Foo extends Enum<Foo> {
    private Foo() {/* calling Enum superconstructor */}
    public static final Foo CONSTANT = new Foo();
}

If you wanted the constant to have a body (to override or declare some methods)

enum Foo {
    CONSTANT {
        public String toString() {
            return name().toUpperCase();
        }
    }
}

becomes something like

class Foo extends Enum<Foo> {
    private Foo() {/* calling Enum superconstructor */}
    public static final Foo CONSTANT = new Foo() { // no way to express an additional interface
        public String toString() {
            return name().toUpperCase();
        }
    };
}
like image 74
Sotirios Delimanolis Avatar answered Feb 11 '23 00:02

Sotirios Delimanolis