Как создать массив обобщенных (Generic) объектов (классов) в Java
Собственно есть шаблонный класс Pair (насколько я знаю, в Java нет уже готовой реализации; если это не так поправте меня):
public class Pair < 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[] examples = new Pair[arraysSize];
И всё вроде бы компилируется и даже работает, но вот IntelliJ кидает мне предупреждение
Unchecked assignment: ‘com.myClass.Pair[]’ to ‘com.myClass.Pair[]’
Попытки дописать хоть куда-то <> не привели к результатам. Собственно вопрос: в чем проблема и как правильно создать массив обобщенных объектов?
Отслеживать
8,937 4 4 золотых знака 19 19 серебряных знаков 28 28 бронзовых знаков
задан 23 мар 2021 в 15:34
48 6 6 бронзовых знаков
Добавьте сюда new Pair[arraysSize]; знаки <> что бы было так new Pair<>[arraysSize]; .
23 мар 2021 в 15:57
@Tsyklop я же говорю, Попытки дописать хоть куда-то <> не привели к результатам.. Если написать так, как ты предлагаешь ( Pair[] examples = new Pair<>[arraysSize]; ), то среда выдаст ошибку: «Cannot infer arguments«. А если скомпилировать, то java напишет: «cannot create array with ‘<>‘«
23 мар 2021 в 16:05
а вы уверены, что нужен именно массив и нельзя использовать List? stackoverflow.com/a/18581313/4908529 Если ответ «да», то для упрощения себе жизни стоило бы сделать конечный класс на основе дженерика class PairString extends Pair и массив делать уже из элементов PairString
23 мар 2021 в 16:32
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
Вы столкнулись с type erasure . Дело в том, что после компиляции дженерики «пропадают». Где бы вы не добавили < >,
Pair[]
по сути превратится в
Pair[]
Пример с вашим классом:
@Test public void typeErasure() < Pair[] 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("s1", "s2"); > Pair integerPair() < return new Pair(1, 2); >
Этит код сгенерирует много предупреждений, но в итоге скомпилируется и исполнится без ошибок. Результат:
class Test$Pair class Test$Pair
Как видите, информация о типах T1, T2 отсутствует.
В итоге: создать действительно дженерик массив нельзя. Лучше используйте List .
Массив объектов в Java. Как добавить объект в массив Java?
Мы уже рассказывали про массивы в Java. В этой статье поговорим про массив объектов и о том, как добавить объект в массив Java. Но сначала давайте вспомним, что массив — это своеобразный контейнер, где может храниться несколько однородных переменных.

Массивы имеют следующие особенности: 1. Хранят переменные лишь одного типа. 2. Имеют определённую длину. 3. Размер массива поменять нельзя. 4. Элементы массива имеют индексы, позволяющие обратиться к этим элементам в случае надобности. 5. Номер 1-го элемента массива — это 0, а не 1; 6. Всегда можно создать пустой массив, а поместить в него элементы можно и потом.
Впрочем, всё это вы уже знаете из предыдущей статьи. Но что такое массив объектов, мы не рассматривали. Впрочем, сейчас мы этот пробел устраним.
Массивы объектов в Java
Массив объектов похож на обычный массив, но имеет другую «начинку». Это связано с тем, что объекты сложнее переменных, т. к. имеют больше составляющих. Но объявление массива объектов происходит так же:

Как видите, мы создаём не массив разных объектов, а массив объектов одного класса. И в начале, и в конце мы указываем название класса, а в квадратных скобках в конце — размер массива.

Какие ошибки делают чаще всего?
У массива объектов есть важная особенность — он включает в себя не объекты сами по себе со всеми их методами и переменными, а лишь ссылки на объекты.

И вот это может стать причиной ошибок. Смотрите, если, к примеру, у нас в массиве есть переменная int и мы не задали её значение, то она по умолчанию станет равна 0. Когда речь идёт про массив объектов — всё иначе. В таком массиве, как уже было сказано, хранятся ссылки на объекты, но пока объект не существует, ссылки тоже не могут существовать. Именно поэтому в массиве объектов по умолчанию хранится значение null. И если вы попытаетесь вызвать метод объекта, который не создан/не существует, получите распространённую ошибку NullPointerException. Это значит, что перед тем, как обращаться к объектам, их обязательно нужно сначала создать, то есть добавить объект в массив Java.
Перейдём к практике
Приступим к созданию массива объектов. Представьте, что у нас есть класс ObjMass и всё, что в нём есть, — это массив объектов Dog из трёх элементов:
public class ObjMass
Прекрасно. Но так как класс Dog мы раньше не описывали (интерпретатор Java знать не знает, что такое Dog и откуда его взять), то название объекта выделится красным. Исправим это, создав параллельно класс Dog:
class ObjMass < Dog[] abc = new Dog [3]; >class Dog
Так, хорошо. Но зачем нам массив, состоящий из пустых объектов? Пусть у собак будут хотя бы клички:
class ObjMass < Dog[] abc = new Dog [3]; >class Dog < String name; public Dog (String name)< this.name = name; >>Вот, теперь Dog имеет содержание.
Давайте сейчас обратимся к объектам, которые ещё не созданы, как говорится, расширим пример. Обратите ваше внимание, что у нас перед массивом объектов Dog находится модификатор static. Также добавим метод main:
class ObjMass < static Dog[] abc = new Dog [3]; public static void main (String[] args)< >> > class Dog < String name; public Dog (String name)< this.name = name; >>Для вывода массива на экран создаём цикл. И выводим не имена собак (abc[i].name), а объекты — abc[i]:
class ObjMass < static Dog[] abc = new Dog [3]; public static void main (String[] args)< for (int i = 0; i> > class Dog < String name; public Dog (String name)< this.name = name; >>И увидим следующий результат:
null null nullЭто и есть значения по умолчанию, при ссылке на которые возникнет ошибка NullPointerException. Она появляется, когда мы ссылаемся на свойство null-ного объекта. К примеру, давайте попробуем вывести на экран имена собак (abc[i].name):
class ObjMass < static Dog[] abc = new Dog [3]; public static void main (String[] args)< for (int i = 0; i> > class Dog < String name; public Dog (String name)< this.name = name; >>Результатом станет тот самый NullPointerException. Чтобы этого не допустить, массив объектов надо заполнить:
class ObjMass < static Dog[] abc = new Dog [3]; public static void main (String[] args)< abc[0] = new Dog("Billy"); abc[1] = new Dog("Tom"); abc[2] = new Dog("Jonny"); for (int i = 0; i> > class Dog < String name; public Dog (String name)< this.name = name; >>Результат выполнения кода:
Billy Tom JonnyВот и всё, теперь вы знакомы с особенностями применения массива объектов в Java и знаете, как добавить объект в массив. В прочих аспектах всё функционирует практически так же, как и в массивах примитивных типов.
Как создать массив объектов java
Массив представляет набор однотипных значений. Объявление массива похоже на объявление обычной переменной, которая хранит одиночное значение, причем есть два способа объявления массива:
тип_данных название_массива[]; // либо тип_данных[] название_массива;Например, определим массив чисел:
int nums[]; int[] nums2;После объявления массива мы можем инициализовать его:
int nums[]; nums = new int[4]; // массив из 4 чиселСоздание массива производится с помощью следующей конструкции: new тип_данных[количество_элементов] , где new - ключевое слово, выделяющее память для указанного в скобках количества элементов. Например, nums = new int[4]; - в этом выражении создается массив из четырех элементов int, и каждый элемент будет иметь значение по умолчанию - число 0.
Также можно сразу при объявлении массива инициализировать его:
int nums[] = new int[4]; // массив из 4 чисел int[] nums2 = new int[5]; // массив из 5 чиселПри подобной инициализации все элементы массива имеют значение по умолчанию. Для числовых типов (в том числе для типа char) это число 0, для типа boolean это значение false , а для остальных объектов это значение null . Например, для типа int значением по умолчанию является число 0, поэтому выше определенный массив nums будет состоять из четырех нулей.
Однако также можно задать конкретные значения для элементов массива при его создании:
// эти два способа равноценны int[] nums = new int[] < 1, 2, 3, 5 >; int[] nums2 = < 1, 2, 3, 5 >;Стоит отметить, что в этом случае в квадратных скобках не указывается размер массива, так как он вычисляется по количеству элементов в фигурных скобках.
После создания массива мы можем обратиться к любому его элементу по индексу, который передается в квадратных скобках после названия переменной массива:
int[] nums = new int[4]; // устанавливаем значения элементов массива nums[0] = 1; nums[1] = 2; nums[2] = 4; nums[3] = 100; // получаем значение третьего элемента массива System.out.println(nums[2]); // 4Индексация элементов массива начинается с 0, поэтому в данном случае, чтобы обратиться к четвертому элементу в массиве, нам надо использовать выражение nums[3] .
И так как у нас массив определен только для 4 элементов, то мы не можем обратиться, например, к шестому элементу: nums[5] = 5; . Если мы так попытаемся сделать, то мы получим ошибку.
Длина массива
Важнейшее свойство, которым обладают массивы, является свойство length , возвращающее длину массива, то есть количество его элементов:
int[] nums = ; int length = nums.length; // 5Нередко бывает неизвестным последний индекс, и чтобы получить последний элемент массива, мы можем использовать это свойство:
int last = nums[nums.length-1];Многомерные массивы
Ранее мы рассматривали одномерные массивы, которые можно представить как цепочку или строку однотипных значений. Но кроме одномерных массивов также бывают и многомерными. Наиболее известный многомерный массив - таблица, представляющая двухмерный массив:
int[] nums1 = new int[] < 0, 1, 2, 3, 4, 5 >; int[][] nums2 = < < 0, 1, 2 >, < 3, 4, 5 >>;Визуально оба массива можно представить следующим образом:
Массив объектов в Java
Ранее на нашем сайте уже была размещена статья, посвященная массивам в Java. В ней мы рассказывали, что массив - это такой " контейнер ", который может вмещать в себя несколько однородных переменных.
У массивов есть несколько особенностей:
1. Они могут хранить переменные только одного типа ;
2. Размер массива нельзя поменять;
3. Массив имеет длину;
4. Элементы массивов имеют индексы, по которым к ним и обращаются в случае необходимости;
5. Номер первого элемента массива - 0 ;
6. Можно создавать пустые массивы, и "положить" в них элементы потом .
А вот что такое "массивы объектов" мы ранее не рассматривали. Давайте разберемся что к чему.
Массив объектов
По сути, у массивов объектов очень много общего с обычными массивами, только у них другая "начинка". Тем не менее, как Вы знаете, объекты гораздо "сложнее", чем переменные, потому что у них есть больше составляющих.
Массив объектов объявляется так же, как и массив переменных:
Как вы видите, у нас не массив разных объектов (стульев, столов и жевательных резинок). Это массив объектов одного класса (массив стульев, например).
Тут тоже все начинается и заканчивается названием класса , а в конце в квадратных скобках указывается размер массива:
Распространенная ошибка
Массив объектов отличается одной особенностью - они состоят из ссылок на объекты:
То есть в массиве не содержатся все переменные и методы каждого объекта, как Вы могли бы подумать, а только ссылки на эти самые объекты. Но тут возникает одна опасность. Обычно переменные в массивах имеют значения по умолчанию - если не задать, например, значение переменной int, то она по умолчанию будет равна 0 (больше информации про значения по умолчанию можно найти здесь).
В случает с объектами, происходит по-другому. В массиве должна храниться ссылка на объект, но пока объекта не существует, - ссылки на него тоже быть не может .
Поэтому, в массиве хранится значение по умолчанию null. Если Вы попробуете вызвать метод не созданного объекта, возникнет распространенная ошибка NullPointerException . Обязательно создайте свои объекты перед тем, как обращаться к ним!
Пример
Давайте создадим массив объектов. Допустим, у нас есть класс - ObjMass, и все, что в нем хранится - это массив объектов Cat из 3 элементов:




