【问题标题】:Enforcing the implementer of an interface to be an enum将接口的实现者强制为枚举
【发布时间】:2016-07-22 13:28:09
【问题描述】:

我想在集合中存储一个名为App 的类型。 App 需要是实现App 接口的枚举。

Set<App> myApps;

我已经定义了这样的接口......

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

这几乎可以工作,例如,你不能这样做......

class MyClass implements Application<MyClass> {}

但是,您可以这样做...

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

这是错误的。我只希望枚举能够实现这个接口,我该如何强制执行?

【问题讨论】:

  • 你从编译器中得到了什么错误信息?请编辑您的帖子,以始终如一地向我们展示您的所有声明。
  • @MikeRobinson 他没有收到错误消息,这就是问题所在 - 他希望编译器抱怨最后的声明。 ;)
  • @MikeRobinson 再次阅读了这个问题。编译器没有错误。 OP 只是想限制实施者。
  • 不是解决方案,但至少是一种改进:interface App&lt;T extends Enum&lt;T&gt; &amp; App&lt;T&gt;&gt;。使用您的版本,即使MyEnum 没有实现App&lt;MyEnum&gt;,您也可以执行class Myclass implements Application&lt;MyEnum&gt;,因此通过改进,您至少可以阻止开发人员使用any 枚举。除此之外,是否有理由要求实现为枚举?是否有办法至少在运行时检查实际类上的isEnum() 标志(例如,当传递App 的实例时)?
  • 接口无法描述它们可以附加到哪些类型,它们只是描述了实现它们的类型的一些强制(保证)行为。您所描述的并不是该语言的真正特性,因此您将很难找到一种方法来创建您所追求的开发防御机制。

标签: java enums interface


【解决方案1】:

定义一个允许您将元素添加到集合中的方法,但对该参数使用约束...

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

现在之后

addToSet(MyEnum.K) will compile

但是

addToSet(new Myclass()) will NOT compile

【讨论】:

  • 所以它几乎是相同的类型参数,除了作为方法声明的一部分而不是接口声明 - 整洁:)
  • 我的套装是什么类型的?
  • 我还没有看到架构,但我怀疑你想调用枚举器正在实现的接口的抽象方法,因此我建议定义一个 Set 将接口保存为 DataType
【解决方案2】:

AFAIK 不可能强制接口的实现者具有某些属性,例如作为枚举。

但是,根据您的代码以及您使用该接口的方式,您可能很难不将实现者设为枚举:

  • 要求T 也实现App&lt;T&gt; 以防止将任何枚举传递给类声明(即App&lt;T extends Enum&lt;T&gt; &amp; App&lt;T&gt;&gt;
  • 尽可能使用额外的边界(参见 ΦXocę 웃 Пepeúpa 的回答)
  • 添加Enum已经实现的方法,如name()ordinal()getDeclaringClass()等。
  • App&lt;T ...&gt; 扩展Comparable&lt;T&gt;
  • 如果可能,请调用getClass().isEnum() 在运行时检查该属性。这并不理想,但有一些常用的类似解决方案,例如 Collections.unmodifiableSet()

【讨论】:

    猜你喜欢
    • 2019-01-20
    • 1970-01-01
    • 2011-02-12
    • 1970-01-01
    • 2020-11-28
    • 2019-06-03
    • 1970-01-01
    • 2013-05-11
    • 2016-09-03
    相关资源
    最近更新 更多