使用枚举作为类的通用类型,但无法创建实例

时间:2019-10-02 20:14:22

标签: java generics enums

我有枚举:

public enum MyTypes {FOO, BAR}

我用通用类型定义了一个类:

public MyClass<T extends MyTypes> {
  private T theType;
  ...
}

以上代码成功编译。

接下来,我尝试创建类型为Foo的MyClass实例作为通用参数:

// Compilation error: Cannot resolve symbol FOO
MyClass<FOO> myInstanceWithFoo = new MyClass();

是因为Java不接受enum类型作为泛型类型吗?如果是这样,是否有解决方法来实现我想要的目标?

2 个答案:

答案 0 :(得分:1)

  

是因为Java不接受枚举类型作为泛型类型吗?

任何枚举类型都是有效类型,并且可以参与形成类型参数(例如MyClass<T extends MyTypes>)和参数化类型(例如MyClass<MyTypes> myInstance)。

你做了什么

MyClass<FOO> myInstanceWithFoo = new MyClass();
由于FOOMyTypes的实例(或对象),因此

永远不会被允许。这不是一种类型,不能这样对待。

  

如果是,是否有解决方法来实现我想要的目标?

MyClass不需要通用。它声明了一个MyTypes字段,该字段可以是MyTypes.FOOMyTypes.BAR(当然也可以是null)。

class MyClass {
  private MyTypes myType;

  public MyClass(MyTypes myType) {
    this.myType = myType;
  }
}

每个MyTypes实例都知道如何从自身创建MyClass

enum MyTypes {
  FOO, BAR;

  public MyClass createMyClass() {
    return new MyClass(this);
  }
}

如何创建它们的示例是

class Example {
  public static void main(String[] args) {
    MyClass myInstanceWithFoo = MyTypes.FOO.createMyClass();
    MyClass myInstanceWithBar = MyTypes.BAR.createMyClass();
  }
}

答案 1 :(得分:0)

我猜测您实际上将FOO作为MyClass的子类型混淆了。

使用“普通”泛型,您可以指定占位符的类型:

public class GenericClass <T extends Object> { // a bit contrived here
    private T generic;
}

已实例化

GenericClass<String> gen = new GenericClass<>(); // String is a subclass of Object

然后将其编译为

public class GenericClass {
   private String generic;
}

请注意,字符串没有值。没有String实例。 为此,我们需要一个setter或构造函数:

public class GenericClass<T extends Object> {
    private T generic;

    public GenericClass(T generic) {
        this.generic = generic;
    }

}

GenericClass<String> gen = new GenericClass<>("Passing in a String because T was a String");

GenericClass<Integer> gen2 = new GenericClass<>(2); // T is integer so we can only pass integers - 2 will be the instance.

因此,对于作为通用类型的Enum,我们要说明类型为MyType。该值将为FOO,因此我们再次需要一个setter或一个构造函数:

public class MyClass<T extends MyTypes> {
    private T theType;

    public MyClass(T theType) {
        this.theType = theType;
    }

}

并确保我们有一个FOO实例,我们将其传递给构造函数

MyClass<MyTypes> myInstanceWithFoo = new MyClass<>(MyTypes.FOO);

希望这很有道理。