我想创建一个参数化(通用)类MyType<T>
及其 builder 。构建器将有一些忽略类型 T
的方法以及一些使用该类型的方法。但似乎使用这种模式我必须重复 T
声明:
how to omit this declaration?
|
V
MyType<String> myType = Builder.<String>of()
.method1(argument_can_be_of_any_type)
.method2(argument_must_be_of_type_T = String)
.build();
是否可以使用一些java语法技巧或其他设计模式来省略第二个类型声明并使API更加用户友好?例如:
List<String> aList = Lists.emptyList();
或
List<String> aList = new LinkedList<>();
我不想在构建器中强制执行任何方法顺序
最佳答案
由于我最初的答案并不像广告中所说的那样有效,所以我对事情进行了一些修改。 (感谢 shmosel 发现问题,感谢 Daniel Pryden 提供建议的解决方案。)
/* contents of Box.java */
public class Box<T>
{
private T contents;
private Object data;
protected Box(T contents, Object data) {
this.contents = contents;
this.data = data;
}
public static BoxBuilder builder() {
return new BoxBuilder();
}
public T getContents() {
return contents;
}
}
/* contents of BoxBuilder.java */
public class BoxBuilder
{
private Object data;
public BoxBuilder withAnything(Object o) {
this.data = o;
return this;
}
// Infers new type from argument
public <T> TypedBoxBuilder<T> withBoxContent(T contents) {
TypedBoxBuilder<T> builder = new TypedBoxBuilder<T>();
builder.setData(data);
builder.setContents(contents);
return builder;
}
}
/* contents of TypedBoxBuilder.java */
public class TypedBoxBuilder<T>
{
private T contents;
private Object data;
public TypedBoxBuilder() {
}
public TypedBoxBuilder<T> withAnything(Object data) {
this.data = data;
return this;
}
public TypedBoxBuilder<T> withContents(T contents) {
this.contents = contents;
return this;
}
public Box<T> build() {
return new Box<T>(contents, data);
}
public void setContents(T contents) {
this.contents = contents;
}
public void setData(Object data) {
this.data = data;
}
}
这是客户端代码:
Box<String> box = Box.builder() // Returns BoxBuilder
.withBoxContent("FOO") // Returns TypedBoxBuilder<String>
.withAnything(42) // Returns TypedBoxBuilder<String>
.build(); // Returns Box<String>
String c = box.getContents();
这也有效:
Box<String> box = Box.builder() // Returns BoxBuilder
.withAnything(42) // Returns BoxBuilder
.withBoxContent("FOO") // Returns TypedBoxBuilder<String>
.build(); // Returns Box<String>
String c = box.getContents();
关于构建器模式中的 java 类型推断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45362662/