Menu
Coddy logo textTech

Обобщенные методы

Часть раздела Объектно-ориентированное программирование путешествия по Java на Coddy. Урок 55 из 87.

Хотя обобщённые классы позволяют целым классам работать с разными типами, иногда обобщённым нужно сделать только один метод. Обобщённый метод объявляет собственный параметр типа, независимый от обобщений на уровне класса.

Параметр типа располагается перед типом return в сигнатуре method:

public class Utility {
    public static <T> void printArray(T[] array) {
        for (T element : array) {
            System.out.println(element);
        }
    }
}

String[] names = {"Alice", "Bob"};
Integer[] numbers = {1, 2, 3};

Utility.printArray(names);    // Работает с String[]
Utility.printArray(numbers);  // Работает с Integer[]

Обратите внимание на <T>, размещённый между модификаторами и типом возвращаемого значения. Это объявляет T параметром типа для данного метода. Компилятор выводит фактический тип из переданных вами аргументов.

Generic-методы также могут возвращать generic-тип:

public static <T> T getFirst(T[] array) {
    if (array.length > 0) {
        return array[0];
    }
    return null;
}

String first = getFirst(new String[]{"a", "b"});  // Возвращает "a"

При необходимости можно использовать несколько параметров типа:

public static <K, V> void printPair(K key, V value) {
    System.out.println(key + ": " + value);
}

printPair("Age", 25);        // String и Integer
printPair(1, "First");       // Integer и String

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

challenge icon

Задание

Легко

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

Вы организуете код в двух файлах:

  • ArrayUtils.java: Создайте класс утилит, содержащий обобщённые методы для работы с массивами. В вашем классе должны быть три статических обобщённых метода:

    getLast — обобщённый метод, который принимает массив типа T и возвращает последний element. Если массив пуст, Return null.

    swap — обобщённый метод, который принимает массив типа T и два integer индекса, затем меняет местами elements на этих positions. Этот метод ничего не возвращает.

    printWithLabel — обобщённый метод с двумя параметрами типа K и V. Он принимает label типа K и значение типа V, затем Prints их в формате: [label]: [value]

  • Main.java: Задействуйте свои обобщённые методы! Вы получите четыре входных значения: два слова (String) и два числа (integer).

    Сначала создайте массив String[], содержащий оба слова. Используйте getLast, чтобы получить последний element, и выведите: Last word: [result]

    Затем создайте массив Integer[], содержащий оба числа. Вызовите swap, чтобы поменять местами elements по индексам 0 и 1, затем выведите: After swap: [first], [second]

    Наконец, продемонстрируйте обобщённый метод с двумя параметрами, дважды вызвав printWithLabel:

    • Один раз, используя первое слово в качестве label, а первое число — в качестве значения
    • Один раз, используя первое число в качестве label, а второе слово — в качестве значения

Вы получите четыре входных значения в следующем порядке: первое слово, второе слово, первое число, второе число.

Обратите внимание, что каждый метод объявляет собственный параметр(ы) типа с помощью <T> или <K, V> перед типом Return. Компилятор выводит фактические типы из переданных вами аргументов: при вызове методов не нужно указывать их явно!

Попробуйте сами

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Прочитать входные данные
        String firstWord = scanner.nextLine();
        String secondWord = scanner.nextLine();
        int firstNumber = scanner.nextInt();
        int secondNumber = scanner.nextInt();
        
        // TODO: Создать массив String[] содержащий оба слова
        
        // TODO: Использовать ArrayUtils.getLast чтобы получить последний элемент
        // Вывести: "Last word: [result]"
        
        // TODO: Создать массив Integer[] содержащий оба числа
        
        // TODO: Вызвать ArrayUtils.swap чтобы поменять местами элементы с индексами 0 и 1
        // Вывести: "After swap: [first], [second]"
        
        // TODO: Вызвать ArrayUtils.printWithLabel с firstWord в качестве label и firstNumber в качестве value
        
        // TODO: Вызвать ArrayUtils.printWithLabel с firstNumber в качестве label и secondWord в качестве value
    }
}
quiz iconПроверьте себя

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

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор Java