使用与类关联的条目创建枚举

Woo*_*low 3 java generics polymorphism enums instanceof

假设我有几个特定的​​类,它们都扩展了一个抽象类,如下所示:

public abstract AbstractClass {
  // abstract stuff here
}

public FirstSpecificClass extends AbstractClass {
  // specific stuff here
}

public SecondSpecificClass extends AbstractClass {
  // specific stuff here
}
Run Code Online (Sandbox Code Playgroud)

我需要创建一个enum其他地方,其中每个条目与一个特定的类连接(关联?); 为此,我将特定的类作为构造函数参数传递并将其作为私有字段存储在枚举中(我还为该字段提供了一个getter方法).我还需要创建一个静态方法,该方法将一个特定类的实例作为参数,并返回相应的枚举元素(或null).我将通过循环每个枚举条目并instanceof与前面提到的私有字段的getter结合使用来完成此操作.这是我的尝试:

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;
  }
}
Run Code Online (Sandbox Code Playgroud)

我似乎误解了如何将类类型存储为一个字段,以便以后可以返回并使用它instanceof.此代码产生了几个编译时错误:

  • (枚举的第2行):构造函数Types(Class<FirstSpecificClass>)未定义
  • (枚举的第3行):构造函数Types(Class<SecondSpecificClass>)未定义
  • (枚举的第17行):不兼容的操作数类型booleanClass<AbstractClass>

我通常不是Java程序员,而且我对泛型的理解instanceof最多也是模糊的,尽管我对OOP的概念有着非常牢固的把握.如何解决这些错误并达到预期效果?

rge*_*man 5

在Java中,泛型是不变的.这意味着a Class<FirstSpecificClass>不是a Class<AbstractClass>,即使a FirstSpecificClass是a AbstractClass.

您可以通过显式允许具有上限通配符的子类型来解决此问题.在需要时? extendsAbstractClass类型参数之前添加.

private Class<? extends AbstractClass> classType;

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

public Class<? extends AbstractClass> getClassType() {
   return this.classType;
}
Run Code Online (Sandbox Code Playgroud)

此外,您必须直接在instanceof运算符的源代码中指定类型,因此不会编译:

if(instance instanceof t.getClassType())
Run Code Online (Sandbox Code Playgroud)

对于运行时解决方案,您可以使用Class对象的isInstance方法:

if(t.getClassType().isInstance(instance))
Run Code Online (Sandbox Code Playgroud)