Какую практическую задачу вы решали с помощью Generics в Java?

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

Ответ

Generics (обобщения) решают задачу создания типобезопасных, переиспользуемых компонентов (классов, интерфейсов, методов), устраняя необходимость приведения типов (casting) и уменьшая дублирование кода.

Пример задачи: Реализация универсального кэша для хранения объектов любого типа с гарантией безопасности типов на этапе компиляции.

Решение с Generics:

public class GenericCache<T> {
    private Map<String, T> storage = new HashMap<>();

    public void put(String key, T value) {
        storage.put(key, value);
    }

    public Optional<T> get(String key) {
        return Optional.ofNullable(storage.get(key));
    }
}

Использование:

// Кэш для строк. Компилятор проверяет типы.
GenericCache<String> userCache = new GenericCache<>();
userCache.put("user:1", "Alice");
String userName = userCache.get("user:1").orElse("Unknown"); // Без приведения типа

// Кэш для чисел. Тот же класс, но другой параметр типа.
GenericCache<Integer> configCache = new GenericCache<>();
configCache.put("maxConnections", 100);

Какие проблемы это решило:

  1. Безопасность типов: Ошибка ClassCastException обнаруживается на этапе компиляции. Нельзя положить Integer в GenericCache<String>.
  2. Устранение дублирования: Не нужно создавать отдельные классы StringCache, IntegerCache.
  3. Улучшение читаемости: Код явно показывает, с каким типом данных работает.
  4. Снижение шаблонного кода: Убраны ручные приведения (String) cache.get(key).