Ogen
Ogen

Reputation: 6709

Enforcing the implementer of an interface to be an enum

I would like to store a type called App inside a set. App needs to be an enum that implements the App interface.

Set<App> myApps;

I have defined the interface like so...

interface App<T extends Enum<T>> {}

This is almost working, for example, you cannot do this...

class MyClass implements Application<MyClass> {}

However, you can do this...

enum MyEnum implements Application<MyEnum> {}
class Myclass implements Application<MyEnum> {}

Which is wrong. I only want enums to be able to implement this interface, how can I enforce this?

Upvotes: 7

Views: 460

Answers (2)

Thomas
Thomas

Reputation: 88727

AFAIK it is not possible to enforce an implementor of an interface to have certain properties such as being an enum.

However, depending on your code and how you use that interface you can make it hard for someone not to make the implementor an enum:

  • Require T to implement App<T> as well to prevent passing any enum to the class declaration (i.e. App<T extends Enum<T> & App<T>>)
  • Use additional boundaries when possible (see ΦXocę 웃 Пepeúpa's answer)
  • Add methods that are already implemented by Enum such as name(), ordinal(), getDeclaringClass() etc.
  • Let App<T ...> extend Comparable<T>.
  • When possible call getClass().isEnum() to check that property at runtime. This is not ideal but there are similar solution's that are commonly used such as Collections.unmodifiableSet().

Upvotes: 1

Define a method that allows you to add Elements into the set, BUT use a constraint for that parameter...

 public <E extends Enum<E> & IMyInterface> void addToSet(final E value) { }

now after that

addToSet(MyEnum.K) will compile

but

addToSet(new Myclass()) will NOT compile

Upvotes: 11

Related Questions