枚举和构建器模式的通用类型

Lee*_*ald 5 java generics type-erasure

我正在尝试创建一个构建器模式,该模式使用泛型来提供某些方法的类型检查.目前我有以下工作:

ParameterBuilder.start(String.class).setName("foo").setDefaultValue("Hello").build();
ParameterBuilder.start(Integer.class).setName(bar).setDefaultValue(42).build();
ParameterBuilder.start(Boolean.class).setName(bar).setDefaultValue(false).build();
Run Code Online (Sandbox Code Playgroud)

使用代码:

public class ParameterBuilder<T> {
  private String name;
  private T defaultValue;

  public static <T2> ParameterBuilder<T2> start(Class<T2> type) {
    return new ParameterBuilder<T2>();
  }
  // Other methods excluded for example
}
Run Code Online (Sandbox Code Playgroud)

因此,setDefaultValue方法的输入类型由传递给方法的内容定义start,就像我想要的那样.

但现在我想扩展传递的内容start()以包含更多信息.基本上我想为我创建的参数传递一个"类型".有时这些参数将是"email","url"等.默认值仍然是已知类型(在这种情况下为String),所以我希望有类似的东西:

ParameterBuilder.start(EMAIL).setName("email").setDefaultValue("foo@bar.com").build();
ParameterBuilder.start(URL).setName("website").setDefaultValue("http://www.somewhere.com").build();
Run Code Online (Sandbox Code Playgroud)

目前,EMAIL和URL是枚举,包含其他内容 - 默认值的类.但是,如果我沿着这条路走下去,我将如何实例化参数构建器?

public static <T2> ParameterBuilder<T2> start(ParameterType paramType) {
  Class<T2> type = paramType.getTypeClass();
  // How do I instantiate my ParameterBuilder with the right type?
}
Run Code Online (Sandbox Code Playgroud)

如果使用枚举无法完成(我可以看到这种情况),是否有人建议使用其他解决方案?

ass*_*ias 2

我认为每个类类型都需要一个枚举(我不明白如何让一个枚举涵盖多种类型并保持其正常工作)。在这种情况下,一个通用的通用接口就可以满足您的需求。然后,您可以创建某种工厂来提供枚举常量(如果有帮助的话)。

这编译:

static interface ParameterType<T> {}

static enum ParameterTypeEnum implements ParameterType<String> { EMAIL; }

public static void main(String[] args) {
    ParameterBuilder
           .start(ParameterTypeEnum.EMAIL)
           .setName("email")
           .setDefaultValue("foo@bar.com")
           .build();
}

public static class ParameterBuilder<T> {

    private String name;
    private T defaultValue;

    public static <T2> ParameterBuilder<T2> start(ParameterType<T2> paramType) {
        return new ParameterBuilder<T2>();
    }

    ParameterBuilder<T> setName(String name) {
        this.name = name;
        return this;
    }

    ParameterBuilder<T> setDefaultValue(T defaultValue) {
        this.defaultValue = defaultValue;
        return this;
    }

    void build() {}
}
Run Code Online (Sandbox Code Playgroud)