Изменение типа параметра конструктора ломает класс в другом фляге

StackOverflow https://stackoverflow.com/questions/1001940

Вопрос

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

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

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

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

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

У меня есть несколько идей, что вызывает это, в соответствии с тем, как конструктор связан в байт-коде зависимого класса, но я не уверен на 100%.

Пожалуйста, кто-нибудь может пролить свет на то, что здесь происходит?

Update

Впоследствии я сделал быстрый тест и посмотрел на байт-код:

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

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

Это было полезно?

Решение

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

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

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

Другие советы

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top