Мосты (синтетические методы) не создаются, если вы на самом деле не пишете метод, как вы это делали в своем последующем тесте, в котором вы указали public boolean add(String o){return super.add(o);}
в коде.
Когда вы вызываете .get(someInt)
навыражение типа StringList
, компилятор может видеть, что ваш тип StringList
, даже если это подтип ArrayList<String>
, не имеет метода с сигнатурой String get(int)
.Следовательно, он генерирует вызов метода Object get()
в байт-коде и, кроме того (если необходимо), приведение типов и на стороне java действует так, как если бы метод get для StringList
возвращает String.Даже если на уровне байт-кода это не так.
Если затем сделать так, чтобы появился метод String get(int)
, например, путем подкласса StringList
или путем редактирования исходного кода и перекомпиляции только этого файла, тогда и только тогдаявляется сгенерированным методом моста.Поскольку Java является динамической диспетчеризацией, этот мост всегда используется.Мост бросает и вызывает (или вызывает и бросает, зависит от того, покрывает ли мост shenanigans возвращаемого типа или shenanigans параметра).
Вы можете проверить все это, используя javap -v
: я настоятельно рекомендую всем, кому это интереснои хочу точно знать, как это работает, развлекаясь, исследуя разницу в результатах между этим:
import java.util.*;
public class Test extends ArrayList<String> {
public static void main(String[] args) {
List raw = new Test();
raw.add(3);
}
}
и этим:
import java.util.*;
public class Test extends ArrayList<String> {
public static void main(String[] args) {
List raw = new Test();
raw.add(3);
}
public boolean add(String o) {
return super.add(o);
}
}