Это метод, который позволяет классу, расширяющему универсальный класс или реализующему универсальный интерфейс (с конкретным параметром типа), по-прежнему использоваться в качестве необработанного типа.
Представьте себе:
public class MyComparator implements Comparator<Integer> {
public int compare(Integer a, Integer b) {
//
}
}
Это нельзя использовать в необработанном виде, передавая два Object
s для сравнения, потому что типы компилируются в метод сравнения (вопреки тому, что произошло бы, если бы это был параметр универсального типа T, где типбудет стерта).Таким образом, вместо этого, за кулисами, компилятор добавляет «метод моста», который выглядит примерно так (если бы это был источник Java):
public class MyComparator implements Comparator<Integer> {
public int compare(Integer a, Integer b) {
//
}
//THIS is a "bridge method"
public int compare(Object a, Object b) {
return compare((Integer)a, (Integer)b);
}
}
Компилятор защищает доступ к методу моста, применяя явные вызовынепосредственно к нему приводят к ошибке времени компиляции.Теперь класс можно использовать и в необработанном виде:
Object a = 5;
Object b = 6;
Comparator rawComp = new MyComparator();
int comp = rawComp.compare(a, b);
Зачем это еще нужно?
В дополнение к добавлению поддержки явного использования необработанных типов (который в основном предназначен дляобратная совместимость) методы моста также необходимы для поддержки стирания типа.При стирании типа такой метод:
public <T> T max(List<T> list, Comparator<T> comp) {
T biggestSoFar = list.get(0);
for ( T t : list ) {
if (comp.compare(t, biggestSoFar) > 0) {
biggestSoFar = t;
}
}
return biggestSoFar;
}
фактически скомпилирован в байт-код, совместимый с этим:
public Object max(List list, Comparator comp) {
Object biggestSoFar = list.get(0);
for ( Object t : list ) {
if (comp.compare(t, biggestSoFar) > 0) { //IMPORTANT
biggestSoFar = t;
}
}
return biggestSoFar;
}
Если метод моста не существует и вы передали List<Integer>
и MyComparator
для этой функции вызов в строке, помеченной IMPORTANT
, будет неудачным, поскольку MyComparator
не будет иметь метода с именем compare
, который занимает два Object
с ... только один, который принимает два Integer
s.
Приведенный ниже FAQ является хорошим чтением.
См. также: