Есть вот такой java класс:
public class SomeType<T> {
public <E> void test(Collection<E> collection) {
for (E e : collection) {
System.out.println(e);
}
}
public void test(List<Integer> list) {
for (Integer integer : list) {
System.out.println(integer);
}
}
}
Если исполнять код так (создать класс любым из трех вариантов):
public static void main(String[] args) {
SomeType someType = new SomeType<>();
//SomeType someType = new SomeType<String>();
//SomeType someType = new SomeType();
List<String> stringList = Arrays.asList("value");
someType.test(stringList);
}
то выбрасывается:
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
И только при таком выполнении
public static void main(String[] args) {
SomeType<String> someType = new SomeType<>();
List<String> stringList = Arrays.asList("value");
someType.test(stringList);
}
код отрабатывает успешно и на экран выводится value
.
Может кто-нибудь объяснить почему именно так работает java? Вроде бы дженерик тип класса T
не связан с дженерик типом метода E
.
И еще, если класс не дженерик:
public class SomeType {
public <E> void test(Collection<E> collection) {
for (E e : collection) {
System.out.println(e);
}
}
public void test(List<Integer> list) {
for (Integer integer : list) {
System.out.println(integer);
}
}
}
то такой код отрабатывает нормально
public static void main(String[] args) {
SomeType someType = new SomeType();
List<String> stringList = Arrays.asList("value");
someType.test(stringList);
}
в первом варианте, вы создает экземпляр SomeType
сырого типа, параметризованные методы экземпляра сырого типа затираются и ваш метод с дженериком Е
, после компиляции, превращается в метод вида :
public Object void test(Collection collection) {
for (Object e : collection) {
System.out.println(e);
}
}
при вызове на вход метода подается List<String>
, так как обобщенные типы инвариантны, параметр List<String>
инвариант для Collection
, не расширяет его, поэтому компилятор не связывает вызов с первым, дженерализированным(до компиляции) методом.
А вот второй метод, превращается в следующее:
public void test(List list) {
for (Integer integer : list) {
System.out.println(integer);
}
}
и может принять на вход лист чего угодно, получает List<String>
и пытается прикастовать элемент к Integer.
Для того чтобы ваш код в первом случае правильно работал вы может подать на вход такую конструкцию Collection stringList = Arrays.asList("value");
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
В RecyclerView ,макет которого состоит из текста + изображения некоторые ImageView криво располагаютсяКак я понял, это связано с RecyclerView, т
Нужно реализовать метод getPath так чтобы он возвращал список ребер, путь не обязательно должен быть оптимальным, но должно учитываться isDirected...
Само приложение хотелось бы создавать на Android studioПрошу подсказать с технологиями, которые стоит использовать в создании (напр