Изменение типа параметра конструктора ломает класс в другом фляге - PullRequest
3 голосов
/ 16 июня 2009

У меня есть следующий класс в общей банке:

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

Затем я изменяю параметр конструктора с List на Collection следующим образом:

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

Восстановление общего jar и запуск системы вызывает NoSuchMethodError в любом зависимом классе, когда он вызывает конструктор, пока я не перекомпилирую этот класс.

У меня есть несколько идей, что вызывает это, в соответствии с тем, как конструктор связан с байт-кодом зависимого класса, но я не уверен на 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, точный конструктор привязан во время компиляции.

Вы узнаете что-то новое каждый день: -)

Ответы [ 3 ]

5 голосов
/ 16 июня 2009

javac точно определяет, какой метод или конструктор вызывать во время компиляции. Это не происходит во время ссылки. Поскольку сигнатура конструктора изменилась, на этапе связывания не удается найти запрошенный метод и, следовательно, выдается ошибка. Вы можете исправить ошибку, предоставив конструкторам - один, который принимает Collection, другой List. Позже может быть добавлен конструктор, принимающий Iterable.

Обратите внимание, универсальные типы не являются частью сигнатуры, поэтому их можно изменять, сохраняя двоичную совместимость. И параметры, и возвращаемые типы являются частью сигнатуры методов (ковариантные возвраты приводят к созданию методов искусственного моста).

В JLS имеется большой большой раздел , определяющий, что именно представляет собой двоичные совместимые изменения.

0 голосов
/ 16 июня 2009

Я думаю, что это может быть проблема с версией библиотеки. Вы уверены, что другой версии библиотеки общего достояния в другом контексте не существует?

0 голосов
/ 16 июня 2009

Импортируете ли вы правильные классы List и Collection? то есть java.util.List и java.util.Collection?

...