У меня есть следующий код:
import java.util.*;
public class Exmp {
public static void main(String[] args) {
List<Integer> integerList = Arrays.asList(1,2,3);
Gen gen = new Gen();
gen.m(integerList);
}
static class Gen<T>{
<T> void m(Collection<T> collection){
for (T s: collection) {
System.out.println(s);
}
}
void m(List<String> list){
for (String s: list) {
System.out.println(s);
}
}
}
}
Никак не могу понять почему вызывается метод со списком строк. Может кто ткнет носом?
Это поведение действительно является наследием до-дженериковой эры и относится к т.н. raw type:
To facilitate interfacing with non-generic legacy code, it is possible to use as a type the erasure (§4.6) of a parameterized type (§4.5) or the erasure of an array type (§10.1) whose element type is a parameterized type. Such a type is called a raw type.
More precisely, a raw type is defined to be one of:
The reference type that is formed by taking the name of a generic type declaration without an accompanying type argument list.
An array type whose element type is a raw type.
A non-static member type of a raw type R that is not inherited from a superclass or superinterface of R.
JLS 4.8
Raw type - это дженерик, использованный без указания типов; в данном случае raw type - это Gen<T>
, который вы создаете как просто Gen
. Т.к. вы не указываете тип, компилятор обрабатывает этот класс по-другому, "сбрасывая" всю generic-информацию, которую может найти:
The type of a constructor (§8.8), instance method (§8.4, §9.4), or non-static field (§8.3) M of a raw type C that is not inherited from its superclasses or superinterfaces is the raw type that corresponds to the erasure of its type in the generic declaration corresponding to C.
JLS 4.8
В том числе сбрасывается информация о List<String>
и Collection<T>
, методы теперь выглядят как просто m(List)
и m(Collection)
. При выборе из этих двух методов компилятор выберет более подходящий - m(List)
, и получится ровно та ситуация, которую мы наблюдаем. Чтобы избежать этого, достаточно вывести Gen
из-под понятия "raw type" - это можно сделать, либо указав произвольный тип (хватит даже Gen<?>
), либо вообще его убрав - у вас и так параметризованный метод, поэтому параметр класса в принципе не нужен.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Есть такая программа, которая парсит файл и вытаскивает из нее нужные данные (Вопрос, ответы и категории) и полученные данные выгружает в ExcelНо...
При нажатии кнопки StartRead вылетает с ошибкойВ чем проблема? И еще вопрос, как эти данные из потока записать в музыкальный файл?
Можно ли вызывать прорисовку скомпилиного листа glCallList между glNewList(list, GL_COMPILE) и glEndList()? Не будет ли ошибка?