用于类的Java Generic Enumerator

时间:2015-12-28 17:48:36

标签: java generics enums

我想创建一个带有类的枚举器,以便在更多代码中获取这些类,但我不能。 我将在示例中解释我想要做什么:

public enum SomeEnumeratorForClasses {
  FIRST_CLASS( "Name 1", FirstClass.class ),
  SECOND_CLASS( "Name 2", SecondClass.class );

  private String name;
  private Class<T> response;

  SomeEnumeratorForClasses ( String name, Class<T> clazz ) {...}

  public Class<T> getResponse() {
    return response;
  }
}

例如,每个类的第一个/第二个都有一些字段/方法示例:

getDescription()

最后在其他课程中我想要这样的东西:

SomeEnumeratorForClasses.FIRST_CLASS.getResponse().getDescription();

但我不能这样做。每个类都继承自其他基类Zero.class示例:

FirstClass extends Zero
SecondClass extends Zero

我也尝试这样做

private Class<T> response;

使用它:

private Class<? extends Zero> response;

但仍然无法发挥作用。

方法getDescription不是静态的,例如是公共字符串:

class FirstClass {
  public String getDescription() {
    return "Text";
  }
}

getDesciptions等一些方法在Zero类中是抽象的。 我该怎么办?

1 个答案:

答案 0 :(得分:0)

如果你知道每个类共享一个构造函数签名(最好是一个公共的no-args版本),你可以编写一个实例化它们的函数。

public class ObjectUtils {
    private ObjectUtils(){}

    public static <T> T init(Class<T> clazz, Object... args) {
        try {

            return (T) Arrays.stream(clazz.getConstructors())
                    .filter(construct -> Objects.equals(args.length, construct.getParameterCount()))
                    .filter(construct -> IntStream.range(0, construct.getParameterTypes().length)
                            .allMatch(val -> construct.getParameterTypes()[val].isAssignableFrom(args[val].getClass())))
                    .findFirst().orElseThrow(() -> new InstantiationException("Could not find compatible constructor."))
                    .newInstance(args);

        } catch (InstantiationException | InvocationTargetException | IllegalAccessException e) {
            throw new RuntimeException("Could not instantiate class for provided arguments.", e);
        }
    }
}

现在,你的枚举可能看起来像:

public enum SomeEnumeratorForClasses {
  FIRST_CLASS( "Name 1", FirstClass.class ),
  SECOND_CLASS( "Name 2", SecondClass.class );

  private String name;
  private Class<? extends Zero> responseClass;

  SomeEnumeratorForClasses ( String name, Class<? extends Zero> responseClass ) {
       this.name = name;
       this.responseClass = responseClass;
  }

  public <T extends Zero> T getResponse() {
    return ObjectUtils.init(responseClass);
  }
}

并像这样使用它:

SomeEnumeratorForClasses.FIRST_CLASS.getResponse().getDescription();