Я наткнулся на пример, который предполагает, что стирание выполняется по-разному в сигнатуре и методе, но я не знаю, почему и как. JLS §8.4.8.3 указывает:
Это ошибка времени компиляции, если объявление типа T имеет метод-член m1 и существует метод m2, объявленный в T, или супертип T, для которого выполняются все следующие условия:
- m1 и m2 имеют одно и то же имя.
- м2 доступен с Т.
- Подпись m1 не является дополнительной подписью (§8.4.2) подписи m2.
- Сигнатура m1 или какого-либо метода, который m1 переопределяет (прямо или косвенно), стирается так же, как сигнатура m2 или какого-либо метода, который m2 переопределяет (прямо или косвенно).
Ошибка времени компиляции приведен пример :
class C<T> {
T id (T x) {...}
}
class D extends C<String> {
Object id(Object x) {...}
}
Объяснение:
Это незаконно, поскольку D.id(Object) является членом D, C.id(String) объявлен в супертипе D и:
- Два метода имеют одинаковое имя, идентификатор
- C.id(String) доступен для D
- Подпись D.id(Object) не является подписью C.id(String)
- Два метода имеют одинаковое стирание
Первые два пункта очевидны, но я не понимаю последние два пункта объяснения. Как два метода могут иметь одинаковое стирание, если выполняется третья точка? С третьей точки кажется, что стирание подписи выполняется с использованием метода параметризованного класса C‹String› (т.е. id(String) вместо id(T)). Если это так, то два метода должны иметь разные стирания, но пример предполагает, что стирание метода выполняется для непараметризованного класса. Итак, как на самом деле применяется стирание к сигнатуре и методу?