Leem.fin
Leem.fin

Reputation: 42612

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:

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:

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

Is it because Java don't accept enum type as generic type? If so, is there a workaround to achieve what I want to achieve?

Upvotes: 0

Views: 274

Answers (2)

Cwrwhaf
Cwrwhaf

Reputation: 324

It's my guess that you're confusing FOO as a subtype as MyClass when it is in fact an instance.

With 'normal' generics you specify the type the placeholder will be:

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. To do this we either need a setter or constructor:

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. The value would be FOO, so again we'd need either a setter or a constructor:

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

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

Hope this makes sense.

Upvotes: 0

Andrew
Andrew

Reputation: 49616

Is it because Java don't accept enum type as generic type?

Any enum type is a valid type and can participate in both forming a type parameter (e.g. MyClass<T extends MyTypes>) and parameterizing a type (e.g. MyClass<MyTypes> myInstance).

What you did

MyClass<FOO> myInstanceWithFoo = new MyClass();

is never corrent since FOO is an instance (or object) of MyTypes. 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. It declares a MyTypes field which could be either MyTypes.FOO or MyTypes.BAR (or null, of course).

class MyClass {
  private MyTypes myType;

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

Each MyTypes instance knows how to create a MyClass from itself.

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();
  }
}

Upvotes: 1

Related Questions