如何在 Java 中制作具有多个枚举的数组列表?

How to make an arraylist with multiple enums in Java?

我正在尝试获取枚举 ArrayList 以便能够接受不同的枚举。

enum foo {f,o,o}
enum bar {b,a,r}

ArrayList<Foo> foo = new Arraylist<>();
foo.add(bar.b); // Doesn't work

抱歉,如果这有点奇怪。

首先,我将假设您有充分的理由构建包含多种类型的列表。 (请参阅下文了解为什么 可能不是 一个好主意。)

这是你的例子……稍微整理了一下

enum Foo {A, B, C}
enum Bar {D, E, F}

ArrayList<Foo> list = new ArrayList<>();
list.add(Bar.D);    // Doesn't work

简单来说,该语句不起作用的原因是 FooBar 是不同的类型。 Bar 个实例不是 Foo 个实例。

什么是work-around?

  • 一种可能的解决方法是:

    ArrayList<Enum<?>> list = new ArrayList<>();
    list.add(Foo.A);
    list.add(Bar.D);
    

    这是可行的,因为所有 enum 类 都是 Enum.

    的子类型

    但缺点是您可以将 任何 enum 值放入列表中。

  • 第二种解决方法是将 FooBar 声明为实现某些自定义接口;例如

    interface Thing {}
    enum Foo implements Thing {A, B, C}
    enum Bar implements Thing {D, E, F}
    
    ArrayList<Thing> list = new ArrayList<>();
    list.add(Foo.A);
    list.add(Bar.D);
    
  • 最终的解决方法是将 FooBar 合并为一个 enum.

请注意,解决方案 2 和 3 本质上是在更改 enum 类型;即改变问题。这可能不适合您。


不幸的是,(目前)无法在Java中声明一个“联合”类型。例如:

ArrayList<Foo | Bar> list = new ArrayList<>();  // Doesn't work!!!

那么为什么我说这可能不是一个好主意?好吧,问题在于,当您将多种类型的实例放入集合中时,您的代码通常必须在对集合执行操作时区分不同的情况;例如

ArrayList<Enum<?>> list = new ArrayList<>();
list.add(Foo.A);
list.add(Bar.D);

for (Enum<?> e: list) {
   if (e instanceof Foo) {
       doSomething((Foo) e);
   } else if (e instanceof Bar) {
       doSomethingElse((Bar) e);
   } else {
       throw new SomethingUnexpectedException("...");
   }
}

最好使用第二种解决方法,但是:

  • 如果你想访问特定于一个或其他枚举的方法或属性,你仍然需要区分和转换,并且

  • Thing 类型不是 Enum 的子类型,因此您不能对(静态)类型为 [=] 的值调用 Enum 方法28=].