Изменение типа параметра конструктора ломает класс в другом фляге
-
05-07-2019 - |
Вопрос
У меня есть следующий класс в общей банке:
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
?
Я думаю, что это может быть проблема с версией библиотеки. Вы уверены, что другой версии библиотеки общего достояния в том же контексте нет?