Question

J'ai la classe suivante dans un pot commun:

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

Je change ensuite le paramètre constructeur d'une liste en un collection comme suit:

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

La reconstruction du fichier jar commun et l’exécution du système génèrent un NoSuchMethodError dans toute classe dépendante lorsqu’il appelle le constructeur jusqu’à ce que je recompile cette classe.

J'ai quelques idées sur la cause de ce problème, à savoir comment le constructeur est lié au bytecode de la classe dépendante, mais je ne suis pas sûr à 100%.

S'il vous plaît, quelqu'un peut-il nous éclairer sur ce qui se passe ici?

Mettre à jour

J'ai par la suite fait un test rapide et jeté un coup d'œil au bytecode:

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

}

Comme Tom l'a dit, et comme vous pouvez le constater à la ligne 13, le constructeur exact est lié à la compilation.

Vous apprenez quelque chose de nouveau chaque jour: -)

Était-ce utile?

La solution

javac résout exactement la méthode ou le constructeur à appeler lors de la compilation. Cela ne se produit pas au moment du lien. Comme la signature du constructeur a changé, l'étape de liaison ne peut pas trouver la méthode demandée et génère donc une erreur. Vous pouvez corriger l'erreur en fournissant aux constructeurs - l'un qui prend un Collection l'autre Liste . Plus tard, un constructeur prenant un Iterable pourrait être ajouté.

Notez que les types génériques ne font pas partie de la signature, ils peuvent donc être modifiés tout en conservant la compatibilité binaire. Les types de paramètre et de retour font partie de la signature des méthodes (les retours covariants entraînent la création de méthodes de pont synthétiques).

Il existe une belle et grande section du JLS définissant exactement ce qui constitue des modifications compatibles binaires.

Autres conseils

Importez-vous les bonnes classes List et Collection? c'est-à-dire java.util.List et java.util.Collection ?

Je pense que cela pourrait être un problème avec la version de la bibliothèque. Êtes-vous sûr qu'il n'y a pas une autre version de la bibliothèque commons ailleurs dans le même contexte?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top