Шаг 63.
Язык программирования Java.
Обобщенные методы

На этом шаге мы рассмотрим обобщенные методы

Java имеется также возможность определить отдельный метод с параметрами (или переменными) типа следующим образом:

class ArrayAlg {
    ...
    public static <T> T getMiddle(T... a) {
        return a[a.length >> 1];
    }
    ...
}

Этот метод определен в обычном, а не в обобщенном классе. Тем не менее это обобщенный метод, на что указывают угловые скобки и переменная типа. Обратите внимание на то, что переменная типа вводится после модификаторов (в данном случае public static) и перед возвращаемым типом.

Обобщенные методы можно определять как в обычных, так и в обобщенных классах. Когда вызывается обобщенный метод, ему можно передать конкретные типы данных, заключая их в угловые скобки перед именем метода, как показано ниже:

String middle = ArrayAlg.<String>getMiddle("param1", "param2", "abacaba");

В данном случае (как и вообще) при вызове метода можно пропустить параметр типа String. У компилятора имеется достаточно информации, чтобы вывести из такого обобщения именно тот метод, который требуется вызвать. Он сравнивает тип параметра метода и приходит выводу, что вместо обобщенного типа T следует подставить тип String, что равнозначно следующему вызову:

String middle = ArrayAlg.getMiddle("param1", "param2", "abacaba");

Выводимость типов в обобщенных методах практически всегда действует исправно. Но иногда компилятор ошибается, и тогда приходятся выяснять причину ошибок компилирования. Рассмотрим следующий пример:

double middle = ArrayAlg.getMiddle(1, 2.0, 3);

Данный код не скомпилируется. Данный код можно интерпретировать двояко и в обоих случаях - правильно. По существу, компилятор выполняет автоупаковку в один объект типа Double и два объекта типа Integer, а затем пытается найти общий супертип для этих классов. И таких типов два: класс Number и интерфейс Comparable, который сам является обобщенным. В этом случае для устранения ошибки методу следует передать все параметры со значениями типа double.

На следующем шаге мы рассмотрим ограничение на переменные типа

Предыдущий шаг Содержание Следующий шаг