Предположим, мы имеем следующий общий классКакой из перегруженных методов будет вызываться во время выполнения, если мы применим стирание типа и почему?
public class SomeType<T> {
public <E> void test(Collection<E> collection){
System.out.println("1st method");
for (E e : collection){
System.out.println(e);
}
}
public void test(List<Integer> integerList){
System.out.println("2nd method");
for (Integer integer : integerList){
System.out.println(integer);
}
}
}
Теперь внутри основного метода мы следующий фрагмент кода
SomeType someType = new SomeType();
List<String> list = Arrays.asList("value");
someType.test(list);
В результате выполнения someType.test(list)
мы получим «2-й метод» в нашей консоли как а также java.lang.ClassCastException
. Насколько я понимаю, причина того, почему выполняется второй метод test
, заключается в том, что мы не используем generics для SomeType
. Таким образом, компилятор мгновенно удаляет всю информацию о генериках из класса (то есть как <T>
, так и <E>
). После этого второго метода test
в качестве параметра будет List integerList
, и, конечно, List
лучше соответствует List
, чем Collection
.
Теперь рассмотрим, что внутри основного метода мы имеем следующий фрагмент кода
SomeType<?> someType = new SomeType<>();
List<String> list = Arrays.asList("value");
someType.test(list);
В этом случае мы получим «1-й метод» в консоли. Это означает, что выполняется первый тестовый метод. Вопрос в том, почему?
Из моего понимания во время выполнения у нас никогда не было никакой информации о дженериках из-за стирания стилей. Итак, почему тогда второй метод test
не может быть выполнен. Для меня второй метод test
должен быть (во время выполнения) в следующей форме public void test(List<Integer> integerList){...}
Не так ли?
У нас нет данных генериков во время выполнения, но выбор метода не выполняется во время выполнения. – user2357112
Хорошо, но как выбрать способ? Есть ли какая-либо конкретная информация в байт-коде, которая сообщает jvm, какой метод вызывать? – ruvinbsu
@ruvinbsu, поскольку компилятор действительно решает, какой метод он должен назвать, да. – SomeJavaGuy