Обобщения Java - концепция стирания
У меня есть некоторый код следующим образом:
public class java_generic {
public static void main(String[] args) {
T t = new X();
t.<Object>m(new Object());
t.<String>m(new String());
}
static class T {
<E> void m (E e){
System.out.println("here is T");
}
}
static class X extends T {
void m (String o){
System.out.println("here is X");
}
}
}
Из моего понимания, после стирания типа, класс T
станет таким:
static class T {
void m (Object e){
System.out.println("here is T");
}
}
и м перегружен.
Как имея m(Object)
а также m(String)
Я ожидаю, что результат будет
here is T
here is X
Тем не менее, результат
here is T
here is T
Интересно, почему результат будет таким.
2 ответа
Решение
Вы в значительной степени ответили на свой вопрос. Вам просто нужно полностью следить за последствиями. Удалите весь код и получите следующее:
public class java_generic {
public static void main(String[] args) {
T t = new X();
t.m(new Object());
t.m(new String());
}
static class T {
void m (Object e){
System.out.println("here is T");
}
}
static class X extends T {
void m (String o){
System.out.println("here is X");
}
}
}
Это, надеюсь, делает очевидным, что X.m
просто не отменяет T.m
и, таким образом, звонок через T
ссылка никогда не может ссылаться X.m
,
Поскольку T является суперклассом X, а экземпляр X назначен суперклассу Object t, вы не можете получить доступ к методам подкласса X. Таким образом, оба
t.<Object>m(new Object());
t.<String>m(new String());
вызывая универсальный метод суперкласса.
Теперь проверьте этот путь -
public class java_generic {
public static void main(String[] args) {
X x = new X();
x.<Object>m(new Object());
x.<String>m(new String());
}
static class T {
<E> void m (E e){
System.out.println("here is T");
}
}
static class X extends T {
void m (String o){
System.out.println("here is X");
}
}
}