1. ホーム

[解決済み] [Solved] Collections.emptyList() returns a List<Object>?

2022-03-31 14:10:01

Question

I'm having some trouble navigating Java's rule for inferring generic type parameters. Consider the following class, which has an optional list parameter:

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

My Java compiler gives the following error:

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

But Collections.emptyList() returns type <T> List<T> , not List<Object> . Adding a cast doesn't help

public Person(String name) {
  this(name,(List<String>)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<T> を返すようにデフォルト設定されています。 List<Object> . このように、typeパラメータを指定することで、期待通りの動作をさせることができます。

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

さて、まっすぐな代入を行う場合、コンパイラは一般的な型パラメータを把握することができます。 これを型推論という。 たとえば、次のような場合だ。

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

とすると emptyList() を呼び出すと、正しく List<String> .