Menu
CoddyTech

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

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

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

Параметр типа указывается перед типом возвращаемого значения в сигнатуре метода:

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 параметром типа для данного метода. Компилятор выводит фактический тип из переданных тобой аргументов.

Обобщённые методы также могут возвращать обобщённый тип:

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 и возвращает последний элемент. Если массив пуст, верни null.

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

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

  • Main.java: Используй свои обобщённые методы! Ты получишь четыре входных значения: два слова (Strings) и два числа (целые числа).

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

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

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

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

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

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

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

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 в качестве метки, а firstNumber — в качестве значения
        
        // TODO: Вызовите ArrayUtils.printWithLabel, передав firstNumber в качестве метки, а secondWord — в качестве значения
    }
}
quiz iconПроверьте себя

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

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

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