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