3

私は共通の瓶に次のクラスを持っています:

public class Common 
{
  public Common(List list)
  {
    ...  
  }  
}

次に、次のようにコンストラクターのパラメーターを a から a に変更ListCollectionます。

public class Common 
{
  public Common(Collection collection)
  {
    ...
  }
}

共通の jar を再構築してシステムを実行すると、NoSuchMethodErrorそのクラスを再コンパイルするまで、コンストラクターを呼び出すときに、依存するクラスで a が発生します。

依存クラスのバイトコードでコンストラクターがどのようにバインドされているかという行に沿って、これを引き起こしている原因についていくつかのアイデアがありますが、100%確信はありません。

ここで何が起こっているのか、誰かに光を当てることができますか?

アップデート

その後、簡単なテストを行い、バイトコードを調べました。

Compiled from "Client.java"
public class Client extends java.lang.Object{
public Client();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   new #2; //class ArrayList
   3:   dup
   4:   invokespecial   #3; //Method java/util/ArrayList."<init>":()V
   7:   astore_1
   8:   new #4; //class Common
   11:  dup
   12:  aload_1
   13:  invokespecial   #5; //Method Common."<init>":(Ljava/util/List;)V
   16:  pop
   17:  return

}

トムが言ったように、13 行目でわかるように、正確なコンストラクターはコンパイル時にバインドされます。

あなたは毎日何か新しいことを学びます:-)

4

3 に答える 3

5

javac は、コンパイル時に呼び出すメソッドまたはコンストラクターを正確に解決します。これは、リンク時には発生しません。コンストラクターの署名が変更されたため、リンクの手順で要求されたメソッドを見つけることができず、エラーがスローされます。コンストラクターに提供することでエラーを修正できます-一方Collectionは他方を取りますList。後で、を受け取るコンストラクターをIterable追加できます。

ジェネリック型は署名の一部を形成しないため、バイナリ互換性を維持しながら変更できることに注意してください。パラメーターと戻り値の両方の型が、メソッドの署名の一部を形成します (共変の戻り値により、合成ブリッジ メソッドが作成されます)。

JLS には、バイナリ互換の変更を構成するものを正確に定義する素晴らしいセクションがあります。

于 2009-06-16T14:58:03.793 に答える
0

正しい List クラスと Collection クラスをインポートしていますか? つまりjava.util.Listjava.util.Collection

于 2009-06-16T14:46:44.597 に答える
-1

ライブラリのバージョンに問題がある可能性があると思います。コモンズ ライブラリの別のバージョンが同じコンテキスト内の別の場所に存在しないことを確信していますか?

于 2009-06-16T14:51:23.557 に答える