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)
如果使用枚举无法完成(我可以看到这种情况),是否有人建议使用其他解决方案?
我认为每个类类型都需要一个枚举(我不明白如何让一个枚举涵盖多种类型并保持其正常工作)。在这种情况下,一个通用的通用接口就可以满足您的需求。然后,您可以创建某种工厂来提供枚举常量(如果有帮助的话)。
这编译:
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)