Имеется 3 различных проблемы:
Стирание типа фактического метода
Мостовые методы при переопределении унаследованного метода
Приведение при вызове метода
Ваш пример:
public static <T extends Animal> T funcA ()
Этот метод не может иметь ничего общего сметоды моста, потому что он статический.
Стирание типа означает, что компилятор исключает (стирает) универсальный тип, поэтому код компилируется так, как будто вы написали:
public static Animal funcA ()
Из-зачто, когда вы затем вызываете метод, приведение добавляется компилятором:
Dog d = (Dog) funcA()
Как вы можете видеть, скомпилированный код не имеет универсальных типов, это все "волшебство", реализованное компиляторомчтобы сделать вид, что дженерики действительно существуют.
Теперь, если вы на самом деле интересовались мостовыми методами и тем, как работает стирание, давайте посмотрим на пример в ссылке , которую вы предоставили.
В этой статье метод в базовых классахs объявлен как:
public class Node<T> {
public void setData(T data)
Erasure компилирует это как:
public class Node {
public void setData(Object data)
В подклассе метод объявлен как:
public class MyNode extends Node<Integer> {
public void setData(Integer data)
Erasure компилирует это как:
public class MyNode extends Node {
public void setData(Integer data)
Теперь компилятор добавляет метод моста, поскольку JVM требуется метод переопределения в подклассе с типом параметра Object
:
@Override
public void setData(Object data) {
setData((Integer) data);
}
Как вы можетевидите, компилятор еще раз добавил приведение. Я надеюсь, что это ответит на ваш вопрос о том, как компилятор знает, какой тип составлять, когда он выполняет стирание.