Как поместить объекты разных классов в один массив в Java?

«Как поместить объекты разных классов в один массив в Java?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Объекты разных классов можно поместить в один массив, если они имеют общего предка. Наиболее общий предок — java.lang.Object.

1. Базовый способ — массив типа Object[]:

Object[] heterogeneousArray = new Object[3];
heterogeneousArray[0] = "Строка";          // String
heterogeneousArray[1] = Integer.valueOf(100); // Integer
heterogeneousArray[2] = new ArrayList<>();    // ArrayList

Недостаток: При извлечении требуется явное и небезопасное приведение типа (cast), которое может вызвать ClassCastException.

String str = (String) heterogeneousArray[0]; // OK
Integer num = (Integer) heterogeneousArray[1]; // OK
// Date date = (Date) heterogeneousArray[2]; // ClassCastException!

2. Более безопасный способ — использование обобщений (Generics) с верхним bounded wildcard (?):

List<Object> list = new ArrayList<>();
list.add("Текст");
list.add(42); // Автоупаковка в Integer
list.add(new File("test.txt"));

Преимущество: Коллекция типобезопасна на этапе добавления (принимает любой Object). Недостаток остаётся тем же — при чтении нужен cast.

3. Правильный способ — использование общего интерфейса или суперкласса: Если классы логически связаны, создайте общий тип.

interface Drawable { void draw(); }

class Circle implements Drawable { /* ... */ }
class Square implements Drawable { /* ... */ }
class Text implements Drawable { /* ... */ }

Drawable[] drawables = new Drawable[] { new Circle(), new Square(), new Text() };
// Нет необходимости в приведении типов:
for (Drawable d : drawables) {
    d.draw(); // Вызовется своя реализация для каждого объекта
}

Вывод: Массив Object[] — это техническая возможность, но она ведет к потере информации о типах. Предпочтительнее проектировать код так, чтобы использовать полиморфизм через общие интерфейсы.