Создание обобщенного метода в Java

Создание обобщенного метода в Java

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

Но можно объявить обобщенный метод, в кото­ром непосредственно используется один или несколько параметров типа. Более того, можно объявить обобщенный метод, входящий в необобщенный класс.

Начнем рассмотрение обобщенных методов с конкретного примера. В приведенной ниже программе объявляется необобщенный класс GenMethDemo, а в нем — статический обобщенный метод isIn().

Этот метод определяет, является ли объект чле­ном массива. Его можно применять к любому типу объектов и массивов, при условии, что массив содержит объекты, совместимые с типом искомого объекта.

Ниже приведен результат выполнения данной программы:

Рассмотрим метод isIn() подробнее. Прежде всего обратите внимание на объ­явление этого метода в следующей строке кода:

Параметр типа объявляется до типа, возвращаемого методом. Обратите так-же внимание на то, что тип Т расширяет обобщенный тип Comparable<T>, где Comparable — это интерфейс, объявляемый в пакете java.lang.

В классе, реализующем интерфейс Comparable, определяются объекты, которые моrут быть упо­рядочены.

Следовательно, указание интерфейса Comparable в качестве верхней границы гарантирует, что метод isIn() вполне применим к объектам, которые можно сравнивать.

Интерфейс Comparable является обобщенным, а параметр его типа обозначает тип сравниваемых объектов. Обратите далее внимание на то, что тип V ограничен с верху типом Т.

Это означает, что тип V должен быть тем же типом, что и Т, или же типом его подкласса. Такая взаимосвязь подразумевает, что метод isIn() может быть вызван только с совместимыми аргументами.

И наконец, обратите внимание на то, что метод isIn() объявлен как статический, что позволяет вызывать его независимо ни от какого объекта.

Следует, однако, иметь в виду, что обобщенные методы могут быть как статическими, так и нестатическими. Никаких ограничений на этот счет не существует.

А теперь обратите внимание на то, что метод isIn() вызывается из метода main() с нормальным синтаксисом вызовов, не требуя указывать аргументы типа.

Дело в том, что типы аргументов различаются автоматически, а типы Т и V соответственно подстраиваются.

Например, в первом вызове этого метода:

первый аргумент относится к типу Integer (благодаря автоупаковке), поэто­му вместо типа Т подставляется тип Integer.

Второй аргумент также относитсяк типу Integer, который подставляется вместо типа V. Во втором вызове данного метода оба аргумента относятся к типу String, который и подставляется вместо типов Т и V.

Для вызовов большинства обобщенных методов, как правило, достаточно и выведения типов, но если требуется, то аргументы типа можно указать явно.

В качестве примера ниже показано, как должен выглядеть первый вызов метода isIn(), если явно указаны оба аргумента типа:

Очевидно, что явное указание аргументов типа в данном случае не дает никаких преимуществ.

Более того, выведение типов в отношении методов было усо­вершенствовано в версии JDК 8. Таким образом, указывать аргументы типа явным образом требуется лишь в крайне редких случаях.

А теперь обратите внимание на приведенный ниже закомментированный кодиз рассматриваемой здесь программы:

Если убрать комментарии из этих строк кода, а затем попытаться скомпилировать данную программу, то возникнет ошибка.

Дело в том, что параметр типа V ограничивается типом Т в выраженииe extends из объявления параметра типа V. Это означает, что параметр типа V должен иметь тип Т или же тип его подкласса.

В данном же случае первый аргумент относится к типу String, а следовательно, второй аргумент также должен относиться к типу String, хотя на самом деле он относится к типу Integer который не является производным от класса String.

В итоге во время компиляции возникает ошибка несоответствия типов. Такая способность обеспечивать типовую безопасность является одним из самых главных преимуществ обобщенных методов.

Синтаксис, использованный для создания метода isIn(), можно обобщить. Ниже приведена общая синтаксическая форма обобщенного метода:

В любом случае список_параметров_типа обозначает разделяемый запятыми список параметров типа.

Обратите внимание на то, что в объявлении обобщенно­го метода список параметров типа предшествует возвращаемому типу.

Интересное видео для нашей аудитории: