Ответ
Объекты разных классов можно поместить в один массив, если они имеют общего предка. Наиболее общий предок — 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[] — это техническая возможность, но она ведет к потере информации о типах. Предпочтительнее проектировать код так, чтобы использовать полиморфизм через общие интерфейсы.