tun*_*opj 6 java generics guava
我试图了解如何Lists.newArrayList()
知道要返回的列表类型.我看到了函数的源代码newArrayList()
,但它只返回ArrayList
泛型类型E.
public static <E> ArrayList<E> newArrayList() {
return new ArrayList<E>();
}
Run Code Online (Sandbox Code Playgroud)
但是,当我调用该函数时,我没有传递任何此类信息.
List<String> testList = Lists.newArrayList();
Run Code Online (Sandbox Code Playgroud)
它是如何知道ArrayList
我想要什么类型的?
我读到了泛型,TypeToken
但无法通过代码与它相关.
Mar*_*rno 14
因为编译器可以从变量声明中推断出类型.
例:
List<String> list = Lists.newArrayList(),
Run Code Online (Sandbox Code Playgroud)
编译器会理解集合的类型(E的类型)<String>
,因为你希望得到一个String列表.
避免重写整个<>参数很有用,但使用Java7和diamond运算符可以避免使用它
List<String> list = new ArrayList<>();
Run Code Online (Sandbox Code Playgroud)
(想象一下,List<List<String>>
你应该重写它List<List<String>>
)
我找到了这个给你:
Java编译器利用目标类型来推断泛型方法调用的类型参数.表达式的目标类型是Java编译器所期望的数据类型,具体取决于表达式的显示位置.考虑方法Collections.emptyList,声明如下:
static <T> List<T> emptyList();
Run Code Online (Sandbox Code Playgroud)
请考虑以下赋值语句:
List<String> listOne = Collections.emptyList();
Run Code Online (Sandbox Code Playgroud)
该语句期待List的实例; 此数据类型是目标类型.因为方法emptyList返回List类型的值,所以编译器推断类型参数T必须是值String.这适用于Java SE 7和8.或者,您可以使用类型见证并指定T的值,如下所示:
List<String> listOne = Collections.<String>emptyList();
Run Code Online (Sandbox Code Playgroud)
但是,在这种情况下,这不是必需的.不过,在其他情况下这是必要的.请考虑以下方法:
void processStringList(List<String> stringList) {
// process stringList
}
Run Code Online (Sandbox Code Playgroud)
假设您要使用空列表调用方法processStringList.在Java SE 7中,以下语句不编译:
processStringList(Collections.emptyList());
Run Code Online (Sandbox Code Playgroud)
Java SE 7编译器生成类似于以下内容的错误消息:
List<Object> cannot be converted to List<String>
Run Code Online (Sandbox Code Playgroud)
编译器需要类型参数T的值,因此它以值Object开头.因此,Collections.emptyList的调用返回List类型的值,该值与方法processStringList不兼容.因此,在Java SE 7中,您必须指定type参数值的值,如下所示:
processStringList(Collections.<String>emptyList());
Run Code Online (Sandbox Code Playgroud)
Java SE 8中不再需要这样.目标类型的概念已经扩展为包含方法参数,例如方法processStringList的参数.在这种情况下,processStringList需要一个List类型的参数.方法Collections.emptyList返回List的值,因此使用List的目标类型,编译器推断类型参数T的值为String.因此,在Java SE 8中,以下语句编译:
processStringList(Collections.emptyList());
Run Code Online (Sandbox Code Playgroud)
有关详细信息,请参阅Lambda表达式中的目标类型.
读这个
归档时间: |
|
查看次数: |
8357 次 |
最近记录: |