Create an enum with elements associated with classes

Suppose I have several concrete classes that extend one abstract class, for example:

public abstract AbstractClass {
  // abstract stuff here
}

public FirstSpecificClass extends AbstractClass {
  // specific stuff here
}

public SecondSpecificClass extends AbstractClass {
  // specific stuff here
}

      

I need to create enum

in a different location where each entry is connected (linked?) To one of the defined classes; for this purpose, I pass the concrete class as a parameter to the constructor and store it as a private field in the enum (I also provided a getter method for this field). I also need to create a static method that takes an instance of one of the concrete classes as an argument and returns the corresponding enum member (or null). I will do this by traversing each enum record and using instanceof

in conjunction with the recipient for the private field mentioned earlier. This is my attempt:

public enum Types {
  FIRST(FirstSpecificClass.class),   // line 2
  SECOND(SecondSpecificClass.class); // line 3

  private Class<AbstractClass> classType;

  private Types(Class<AbstractClass> classType) {
    this.classType = classType;
  }

  public Class<AbstractClass> getClassType() {
    return this.classType;
  }

  public static Types fromTypeInstance(AbstractClass instance) {
    for(Types t : Types.values())
      if(instance instanceof t.getClassType()) return t; // line 17
    return null;
  }
}

      

I seem to be misunderstanding how to store the class type as a field so that it can be returned and used in the test instanceof

later. This code generates several compile-time errors:

  • (enumeration line 2): constructor Types(Class<FirstSpecificClass>)

    is undefined
  • (enumeration line 3): constructor Types(Class<SecondSpecificClass>)

    is undefined
  • (enumeration line 17): Incompatible operand types boolean

    andClass<AbstractClass>

I'm not usually a Java programmer, and my understanding of generics instanceof

is vague at best, although I have a fairly clear understanding of the OOP concept. How can I eliminate these errors and achieve the desired effect?

+3


source to share


1 answer


In Java, generics are invariant. This means that a is Class<FirstSpecificClass>

not Class<AbstractClass>

, even if a FirstSpecificClass

is AbstractClass

.

You can work around this by explicitly allowing subtypes with the upper bound wildcard. Add ? extends

before the type argument AbstractClass

if necessary.

private Class<? extends AbstractClass> classType;

private Types(Class<? extends AbstractClass> classType) {
   this.classType = classType;
}

public Class<? extends AbstractClass> getClassType() {
   return this.classType;
}

      

Also, you have to specify the type directly in the source code for the operator instanceof

, so this won't compile:



if(instance instanceof t.getClassType())

      

Instead, you can use the object method to solve at runtime: Class

isInstance

if(t.getClassType().isInstance(instance))

      

+5


source







All Articles