28

Java関数を定義しました:

static <T> List<T> createEmptyList() {
    return new ArrayList<T>();
}

それを呼び出す1つの方法は次のようになります。

List<Integer> myList = createEmptyList(); // Compiles

ジェネリック型の引数を明示的に渡して呼び出せないのはなぜですか?:

Object myObject = createEmtpyList<Integer>(); // Doesn't compile. Why?

Illegal start of expressionコンパイラからエラーが発生します。

4

3 に答える 3

44

When the java compiler cannot infer the parameter type by itself for a static method, you can always pass it using the full qualified method name: Class . < Type > method();

Object list = Collections.<String> emptyList();
于 2008-08-25T11:28:51.017 に答える
26

タイプをメソッドパラメータとして渡すと、可能になります。

static <T> List<T> createEmptyList( Class<T> type ) {
  return new ArrayList<T>();
}

@Test
public void createStringList() {
  List<String> stringList = createEmptyList( String.class );
}

メソッドは型と同じ方法でジェネリック化することはできないため、動的に型付けされたジェネリックリターン型(一口です:-)-を持つメソッドの唯一のオプションは、型を引数として渡すことです。

Javaジェネリックに関する本当に優れたFAQについては、AngelikaLangerのジェネリックFAQを参照してください。


ファローアップ:

このコンテキストでは、のように配列引数を使用することは意味がありませんCollection.toArray( T[] )。配列が使用される唯一の理由は、同じ(事前に割り当てられた)配列が結果を含むために使用されるためです(配列がすべてに収まるほど大きい場合)。これにより、実行時に常に新しいアレイを割り当てる必要がなくなります。

ただし、教育の目的で、配列型を使用したい場合、構文は非常に似ています。

static <T> List<T> createEmptyList( T[] array ) {
  return new ArrayList<T>();
}

@Test
public void testThing() {
  List<Integer> integerList = createEmptyList( new Integer[ 1 ] );
}
于 2008-08-24T12:21:39.183 に答える
0

@pauldoo はい、あなたはまったく正しいです。これは、Javaジェネリックの弱点の1つです。

T[] AbstractCollection#toArray (T[] a)など、Java ユーザー自身がどのようにそれを行っているかについても検討することを提案したいと思います。Cheekysofts版の方が優れていると思いますが、Java版の方が親しみやすいというメリットがあります。

編集:リンクを追加しました。再編集: SO にバグが見つかりました :)


Cheekysoft のフォローアップ: まあ、これは返されるべき型のリストなので、対応する例は次のようになります。

static <T> List<T> createEmptyList( List<T> a ) {
  return new ArrayList<T>();
}

しかし、はい、クラス オブジェクトを渡す方が明らかに優れています。私の唯一の議論は親しみやすさであり、この正確な例ではあまり価値がありません(実際には悪いです)。

于 2008-08-24T12:37:16.617 に答える