Java Урок 64: ОБОБЩЕНИЯ, обобщенный метод

Опубликовано: 01.09.2018

видео Java Урок 64: ОБОБЩЕНИЯ, обобщенный метод

C++Now 2018: Arthur O'Dwyer “An Allocator is a Handle to a Heap”

Методы внутри обобщенного класса могут использовать параметр типа, а

следовательно, обобщения относятся также к параметрам методов. Однако


Java 5 Autoboxing

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

Скачать исходники для статьи можно ниже

Начнем с примера.

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

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

// Демонстрация простого обобщенного метода, class GenMethDemo { // Определение, содержится ли объект в массиве. static <Т, V extends Т> boolean isIn(T х, V[] у) { for(int i=0; i < у.length; i++){ if(x.equals(y[i])) return true; } return false; } public static void main(String args[]) { // Применение isln() для Integer. Integer nums[] = { 1, 2, 3, 4, 5 }; if(isIn(2, nums)){ System.out.println("2 содержится в nums"); } if(!isIn(7, nums)){ System.out.println("7 не содержится в nums"); } System.out.println(); // Применение isIn() для String. String strs[] = { "один", "два", "три", "четыре", "пять" }; if(isIn("два", strs)){ System.out.println("два содержится в strs"); } if(!isIn("семь", strs)) { System.out.println("семь не содержится в strs"); } // He скомпилируется! Типы должны быть совместимыми. // if(isIn("два", nums)) // System.out.println("два содержится в strs "); } }

Результат работы этой программы показан ниже:

2 содержится в nums

7 не содержится в nums

два содержится в strs

семь не содержится в strs

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

static <Т, V extends Т> boolean isIn(T х, V[] у) {

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

Также обратите внимание на то, что метод isIn() статический, что позволяет вызывать его независимо от какого-либо объекта. Однако ясно, что обобщенные методы могут быть как статическими, так и нестатическими. Нет никаких ограничений на этот счет.

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

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

Например, в вызове if (isIn(2, nums)) тип первого аргумента — Integer (благодаря автоупаковке), поэтому вместо параметра Т подставляется класс Integer.

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

Теперь обратите внимание на закомментированный код.

// if(isIn("два", nums)) // System.out.println("два содержится в strs ");

Если вы уберете комментарии с этих строк, а затем попытаетесь скомпилировать программу, то получите ошибку. Причина в том, что тип параметра типа V ограничен типом параметра типа Т в конструкции extends объявления параметра типа V.

Это значит, что параметр V должен иметь либо тип Т, либо тип его

подкласса. А в этом случае первый аргумент имеет тип String, но второй — тип Integer, который не является подклассом класса String. Это вызовет ошибку несоответствия типов во время компиляции. Такая способность обеспечивать безопасность типов — одно из наиболее существенных преимуществ обобщенных методов.

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

Вот синтаксис обобщенного метода:

<список_параметров_типа> ссылочный_тип имя_метода (список_параметров) {//...

Во всех случаях список_параметров_типа — это разделенный запятыми список параметров типа. Обратите внимание на то, что для обобщенного метода список параметров типа предшествует типу возвращаемого значения.

rss