Chr*_*way 260 java generics type-inference
我在导航Java规则以推断泛型类型参数时遇到了一些麻烦.考虑以下类,它具有可选的list参数:
import java.util.Collections;
import java.util.List;
public class Person {
private String name;
private List<String> nicknames;
public Person(String name) {
this(name,Collections.emptyList());
}
public Person(String name,List<String> nicknames) {
this.name = name;
this.nicknames = nicknames;
}
}
Run Code Online (Sandbox Code Playgroud)
我的Java编译器给出以下错误:
Person.java:9: The constructor Person(String, List<Object>) is undefined
Run Code Online (Sandbox Code Playgroud)
但是Collections.emptyList()返回类型<T> List<T>,而不是List<Object>.添加演员表无济于事
public Person(String name) {
this(name,(List<String>)Collections.emptyList());
}
Run Code Online (Sandbox Code Playgroud)
产量
Person.java:9: inconvertible types
Run Code Online (Sandbox Code Playgroud)
使用EMPTY_LIST而不是emptyList()
public Person(String name) {
this(name,Collections.EMPTY_LIST);
}
Run Code Online (Sandbox Code Playgroud)
产量
Person.java:9: warning: [unchecked] unchecked conversion
Run Code Online (Sandbox Code Playgroud)
而以下更改会使错误消失:
public Person(String name) {
this.name = name;
this.nicknames = Collections.emptyList();
}
Run Code Online (Sandbox Code Playgroud)
任何人都可以解释我在这里遇到的类型检查规则,以及解决它的最佳方法吗?在这个例子中,最终的代码示例是令人满意的,但是对于更大的类,我希望能够在没有重复代码的情况下编写遵循这个"可选参数"模式的方法.
额外信用:什么时候适合使用EMPTY_LIST而不是emptyList()?
小智 436
您遇到的问题是,即使该方法emptyList()返回List<T>,您还没有提供类型,因此它默认返回List<Object>.您可以提供type参数,并使代码按预期运行,如下所示:
public Person(String name) {
this(name,Collections.<String>emptyList());
}
Run Code Online (Sandbox Code Playgroud)
现在,当您进行直接赋值时,编译器可以为您计算泛型类型参数.它被称为类型推断.例如,如果你这样做:
public Person(String name) {
List<String> emptyList = Collections.emptyList();
this(name, emptyList);
}
Run Code Online (Sandbox Code Playgroud)
然后emptyList()调用将正确返回a List<String>.
car*_*son 95
你想用:
Collections.<String>emptyList();
Run Code Online (Sandbox Code Playgroud)
如果你看一下emptyList的来源,你会发现它实际上只是做了一个
return (List<T>)EMPTY_LIST;
Run Code Online (Sandbox Code Playgroud)
Dan*_*ton 26
emptyList方法有这个签名:
public static final <T> List<T> emptyList()
Run Code Online (Sandbox Code Playgroud)
该<T>字之前列表意味着它推断被分配给从可变结果的类型的一般参数T的值.所以在这种情况下:
List<String> stringList = Collections.emptyList();
Run Code Online (Sandbox Code Playgroud)
然后,返回值由类型的变量显式引用List<String>,因此编译器可以解决它.在这种情况下:
setList(Collections.emptyList());
Run Code Online (Sandbox Code Playgroud)
编译器没有明确的返回变量用于计算泛型类型,因此它默认为Object.
| 归档时间: |
|
| 查看次数: |
203691 次 |
| 最近记录: |