java - 为什么builder会丢失类型?
问题描述
当我尝试这样的事情时
public class Example<T> {
private T value;
private Example() {
}
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
public static <T> Builder<T> builder() {
return new Builder<>();
}
public static class Builder<T> {
public Example<T> build() {
return new Example<>();
}
}
public static void main(String[] args) {
Example<String> example = Example.builder().build();
example.setValue("test");
System.out.println(example.getValue().toUpperCase());
}
}
我收到一个错误
Example.java:27: error: incompatible types: Example<Object> cannot be converted to Example<String>
Example<String> example = Example.builder().build();
但是当我将类型添加到builder
方法的参数时,一切正常
public static <T> Builder<T> builder(T type) {
return new Builder<>();
}
为什么?以及如何摆脱这种虚拟类型参数?
奖励问题:如何将复杂类型传递给这样的方法?
public static <T> Builder<T> builder(Class<T> type) {
return new Builder<>();
}
Example<Optional<String>> example = Example.builder(???).build();
更新:这只是一个例子。现实生活中的应用程序将有几个构建器在构建过程的不同阶段相互创建,当然,它们将具有接受泛型类型的方法。我希望有一种方法可以帮助编译器推断类型。我什至同意反射技巧,如果有的话,它们可以帮助我获得漂亮的 DSL。
解决方案
Example
是一个原始类,所以隐含T
的是Object
. 您可以在调用方法时指定泛型类型,方法是在方法调用之前将其放在尖括号 ( <>
) 中:
Example<String> example = Example.<String>builder().build();
// Here --------------------------^
推荐阅读
- jquery - 数据表在行中隐藏/显示类
- javascript - 擦除()函数完成时如何执行类型()函数
- algorithm - 幸运日黑客地球问题给出错误答案
- sql - 获取值在至少一列中的所有行
- php - db准备插入多个数据库
- javascript - 将帐户分配给 Web 套接字连接
- perl - Perl 和参数化语句
- firebase - 尽管我使用了 SHA-1,但从 Play 商店下载后 Flutter App 显示空白屏幕
- reactjs - 搜索和过滤不起作用反应 redux-thun
- selenium - ExpectedConditions.visibilityOfElementLocated() 和 ExpectedConditions.presenceOfElementLocated() 之间的区别