Как создать массив обобщенных (Generic) объектов (классов) в Java
Собственно есть шаблонный класс Pair (насколько я знаю, в Java нет уже готовой реализации; если это не так поправте меня):
public class Pair<T1, T2> {
public Pair(T1 value1, T2 value2) {
this.value1 = value1;
this.value2 = value2;
}
public T1 getValue1() {
return value1;
}
public T2 getValue2() {
return value2;
}
private final T1 value1;
private final T2 value2;
}
И мне нужно создать массив объектов этого класса. Делаю я это так:
Pair<String, String>[] examples = new Pair[arraysSize];
И всё вроде бы компилируется и даже работает, но вот IntelliJ кидает мне предупреждение
Unchecked assignment: 'com.myClass.Pair[]' to 'com.myClass.Pair<java.lang.String,java.lang.String>[]'
Попытки дописать хоть куда-то <> не привели к результатам.
Собственно вопрос: в чем проблема и как правильно создать массив обобщенных объектов?
Ответы (2 шт):
Вы столкнулись с type erasure.
Дело в том, что после компиляции дженерики "пропадают". Где бы вы не добавили < >,
Pair<String, String>[]
по сути превратится в
Pair[]
Пример с вашим классом:
@Test
public void typeErasure() {
Pair<String, String>[] arr = new Pair[10];
arr[0] = stringPair();
arr[1] = integerPair();
System.out.println(arr[0].getClass());
System.out.println(arr[1].getClass());
}
Pair stringPair() {
return new Pair<String, String>("s1", "s2");
}
Pair integerPair() {
return new Pair<Integer, Integer>(1, 2);
}
Этит код сгенерирует много предупреждений, но в итоге скомпилируется и исполнится без ошибок. Результат:
class Test$Pair
class Test$Pair
Как видите, информация о типах T1, T2 отсутствует.
В итоге: создать действительно дженерик массив нельзя. Лучше используйте List.
Да, идея предупреждает о таком и даже специально для этого придумали аннотацию - в вашем случае она выглядит как @SuppressWarnings("unchecked"); Как бы говоря компилятору: расслабься, так надо.)
Ссылка на доки: https://docs.oracle.com/javase/7/docs/api/java/lang/SuppressWarnings.html