Collections.emptyList() 返回 List<Object>?

2022-08-31 05:18:08

我在导航Java规则以推断泛型类型参数时遇到了一些麻烦。请考虑以下类,它具有可选的列表参数:

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;
  }
}

我的 Java 编译器给出了以下错误:

Person.java:9: The constructor Person(String, List<Object>) is undefined

但返回类型 ,而不是 。添加演员阵容无济于事Collections.emptyList()<T> List<T>List<Object>

public Person(String name) {
  this(name,(List<String>)Collections.emptyList());
}

收益 率

Person.java:9: inconvertible types

使用而不是EMPTY_LISTemptyList()

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_LISTemptyList()


答案 1

您遇到的问题是,即使该方法返回 ,您也没有为其提供类型,因此它默认返回 。您可以提供 type 参数,并让代码按预期运行,如下所示:emptyList()List<T>List<Object>

public Person(String name) {
  this(name,Collections.<String>emptyList());
}

现在,当您执行直接赋值时,编译器可以为您找出泛型类型参数。这称为类型推断。例如,如果您执行以下操作:

public Person(String name) {
  List<String> emptyList = Collections.emptyList();
  this(name, emptyList);
}

则调用将正确返回 .emptyList()List<String>


答案 2

您想使用:

Collections.<String>emptyList();

如果你看一下空列表的来源,你会发现它实际上只是做了一个

return (List<T>)EMPTY_LIST;

推荐