简体   繁体   English

使用枚举作为我的 class 的通用类型,但未能创建实例

[英]Use enum as generic type of my class but failed to create instance

I have Enum:我有枚举:

public enum MyTypes {FOO, BAR}

I defined a class with generic types:我用泛型定义了一个 class :

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

Above code compiles successfully.以上代码编译成功。

Next, I try to create an instance of MyClass with type Foo as the generic parameter:接下来,我尝试创建一个 MyClass 的实例,类型为 Foo 作为泛型参数:

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

Is it because Java don't accept enum type as generic type?是因为 Java 不接受enum类型作为泛型类型吗? If so, is there a workaround to achieve what I want to achieve?如果是这样,是否有解决方法来实现我想要实现的目标?

Is it because Java don't accept enum type as generic type?是因为 Java 不接受枚举类型作为泛型类型吗?

Any enum type is a valid type and can participate in both forming a type parameter (eg MyClass<T extends MyTypes> ) and parameterizing a type (eg MyClass<MyTypes> myInstance ).任何枚举类型都是有效类型,并且可以参与形成类型参数(例如MyClass<T extends MyTypes> )和参数化类型(例如MyClass<MyTypes> myInstance )。

What you did你做了什么

MyClass<FOO> myInstanceWithFoo = new MyClass();

is never corrent since FOO is an instance (or object) of MyTypes .永远不会正确,因为FOOMyTypes的实例(或对象)。 It's not a type, and can't be treated as such.它不是一种类型,不能这样对待。

If so, is there a workaround to achieve what I want to achieve?如果是这样,是否有解决方法来实现我想要实现的目标?

There is no need for MyClass to be generic. MyClass没有必要是通用的。 It declares a MyTypes field which could be either MyTypes.FOO or MyTypes.BAR (or null , of course).它声明了一个MyTypes字段,它可以是MyTypes.FOOMyTypes.BAR (当然也可以是null )。

class MyClass {
  private MyTypes myType;

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

Each MyTypes instance knows how to create a MyClass from itself.每个MyTypes实例都知道如何从自身创建一个MyClass

enum MyTypes {
  FOO, BAR;

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

An example of how to create them would be如何创建它们的一个例子是

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

It's my guess that you're confusing FOO as a subtype as MyClass when it is in fact an instance.我猜您将 FOO 混淆为 MyClass 的子类型,而实际上它是一个实例。

With 'normal' generics you specify the type the placeholder will be:使用“正常” generics 您可以指定占位符的类型:

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

which is instantiated这是实例化的

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

this is then compiled to然后编译为

public class GenericClass {
   private String generic;
}

Notice there is no value for the String.请注意,字符串没有值。 There is no String instance.没有 String 实例。 To do this we either need a setter or constructor:为此,我们需要一个 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");

or或者

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

So for the Enum as a generic type we're stating the type which is MyType.因此,对于作为泛型类型的 Enum,我们声明的类型是 MyType。 The value would be FOO, so again we'd need either a setter or a constructor:该值将是 FOO,所以我们需要一个 setter 或一个构造函数:

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

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

}

and to make sure we're have a FOO instance we pass it in to the constructor为了确保我们有一个 FOO 实例,我们将它传递给构造函数

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

Hope this makes sense.希望这是有道理的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM