На этом шаге мы начнем говорить про обобщенное программирование
Обобщенное программирование означает написание кода, который может быть неоднократно использован с объектами самых разных типов. Простейшим примером такого кода является класс ArrayList, который представляет из себя список объектов одного типа (ArrayList - это коллекция, с которыми мы познакомимся позднее).
До появления версии Java SE 5.0 обобщенное программирование на Java всегда реализовывалось посредством наследования. Так, в классе ArrayList просто поддерживался массив ссылок на класс Object следующим образом:
public class ArrayList { private Object[] elementData; ... public Object get(int i) {...} public void add(Object o) {...} ... }
Такой подход порождает две серьезные проблемы. Всякий раз, когда извлекается значение, необходимо выполнить приведение типа, как показано ниже:
ArrayList files = new ArrayList();
...
String fileName = (String) files.get(0);
Более того, в таком коде отсутствует проверка ошибок. Ничто не мешает добавить значения любого класса следующим образом:
files.add(new File("..."));
Этот вызов компилируется и выполняется без ошибок. Но затем попытка привести результат выполнения метода get() к типу String приведет к ошибке.
Обобщения предлагают лучшее решение: параметры типа. На данный момент класс ArrayList принимает параметр типа, обозначающий тип элементов коллекции, как показано ниже:
ArrayList<String> files = new ArraList<String>();
Благодаря этому код получается более удобочитаемым. Теперь становится сразу понятно, что этот конкретный списочный массив содержит объекты типа String.
Заметим, что, начиная с версии Java SE 7, обобщенный тип можно опускать в объявлении конструктора класса, как показано ниже:
ArrayList<String> files = new ArraList<>();
Обобщенный тип выводится из типа переменной.
Заметим, что теперь для метода get() никакого приведения типов не требуется. Компилятору известно, что возвращаемым типом является String, а не Object:
String fileName = files.get(0);
По той же самой причине, компилятору известно, что у метода add() из класса ArrayList<String> имеется параметр типа String. Это защищает нас от таких случаев как:
files.add(new File("..."));
Такой код не скомпилируется, так как в коллекцию files можно добавлять только объекты класса String. Ошибка компилирования намного лучше чем, исключительная ситуация во время выполнения программы. В этом и состоит задача обобщенного программирования: исходный код становится более удобочитаемым и безопасным.
На следующем шаге мы рассмотрим как создавать простые обобщенные классы