3

コード (コンパイル):

    for (Method m : ImmutableList.class.getMethods()) {
        System.out.println(m);
    }

    ImmutableList.copyOf(Arrays.asList(new PlayerLevel[0]));

出力 (注釈付きで短縮):

public final void com.google.common.collect.ImmutableList.add(int,java.lang.Object)
----> public static com.google.common.collect.ImmutableList com.google.common.collect.ImmutableList.copyOf(java.lang.Iterable)
public static com.google.common.collect.ImmutableList com.google.common.collect.ImmutableList.copyOf(java.util.Iterator)
                 (lots of other methods)

java.lang.NoSuchMethodError: com.google.common.collect.ImmutableList.copyOf(Ljava/util/Collection;)Lcom/google/common/collect/ImmutableList;

は?

(ログが十分に明確でない場合、それImmutableList.copyOf(List)はメソッドではないというエラーが表示されますが、すべてのメソッドをループすると、copyOf(Iterable)、およびがあることがわかりList implements Iterableます。)

4

1 に答える 1

6

どちらの方法も、コンパイル時に互換性があります。しかし、ランタイムは別の獣です。コードは古いバージョンの Google Collections に対してコンパイルされますが、新しいバージョンに対して実行されると思います。

編集:詳細に何が起こるか:

行を考えると

List<String tmpArray = Arrays.asList(new PlayerLevel[0]);
ImmutableList.copyOf(tmpArray);

コンパイラは、静的な型と互換性ImmutableListのある名前copyOfと 1 つのパラメーターを使用して、適切なメソッドを探し始めます。コンパイラに表示されるクラスのバージョンは、正確に 1 つの一致を提供します。List<String>

ImmutableList.copyOf(Collection<T> arg0);

コンパイラは の実際の型には関心がなく静的型 (別名「形式型」) のみが考慮されることに注意してください。tmpArray

コンパイラは、選択したメソッドのシグネチャをクラス ファイルに書き込みます。

実行時に、クラスローダー/リンカがクラスを読み取り、メソッドの署名を見つけます

ImmutableList.copyOf(Collection<T> arg0);

そして、指定された署名を正確にルックアップ(検索ではありません!) を実行します。ここでは互換性は問題ではありません。それはコンパイラの仕事でした。次のようにリフレクションを使用すると、同じ結果が得られます。ImmutableList

ImmutableList.class.method("copyOf", Collection.class);

どちらの場合も、Javaは指定された型を正確に使用してルックアップを実行するだけです。「指定された型で呼び出すことができる戻りメソッド」のような検索は実行しません。

あなたの場合、実行時のクラスパスとコンパイル時のクラスは異なります。そのため、クラスローダー/リンカーはルックアップを実行できません。

一歩後退

この問題は、さまざまなレベルの互換性を示しています。

  • バイナリ互換性: 新しい jar を投入するだけです。
  • ソースの互換性: ソースをコンパイルする必要がありますが、変更する必要はありません。
  • 動作の互換性またはセマンティックな互換性: クライアント コードを変更する必要があります。

これらのキーワードを使用して、このサイトを調べたり、Google で詳細情報を確認したりできます。バイナリ互換性の良いリファレンスは、Evolving Java-based APIsの 3 つの部分です。

于 2011-11-04T15:16:22.413 に答える