Методы в Java
Определяйте и вызывайте методы в Java — типы возвращаемых значений, параметры и тело метода — чтобы организовать переиспользуемый код.
Метод в Java — это именованный блок кода, который вы можете вызвать из другого места в программе. Методы — это то, как вы избегаете повторений: вместо того чтобы писать один и тот же расчёт или одну и ту же пятистрочную операцию в трёх местах, вы помещаете её в метод и вызываете его трижды.
Вы уже видели один метод на каждой странице этой книги — main. Любая программа Java — это всего лишь класс с по меньшей мере одним методом, который JVM умеет запускать. В этой части книги мы рассмотрим, как писать собственные.
Анатомия метода
Объявление метода имеет до пяти частей: модификаторы, тип возвращаемого значения, имя, список параметров и тело.
public static int square(int n) {
return n * n;
}public static— модификаторы.publicуправляет видимостью;staticозначает, что метод принадлежит классу, а не экземпляру. Мы углубимся в оба в последующих частях; пока что каждый метод, который вы пишете в служебном классе верхнего уровня, будетpublic static.int— тип возвращаемого значения. Вид значения, которое метод отдаёт своему вызывающему. Используйтеvoid, если он ничего не возвращает.square— имя. По соглашению lowerCamelCase, глагол или глагольная фраза, говорящая о том, что метод делает.(int n)— список параметров. Входные данные, которые должен предоставить вызывающий. Каждый параметр — это тип и имя.{ ... }— тело. Код, который выполняется при вызове метода.
Вызов метода
После определения вы вызываете метод, написав его имя, за которым следует (...) со значениями аргументов:
int result = square(7); // result равно 49
System.out.println(square(3) + square(4)); // 9 + 16 = 25Значение, которое возвращает метод, можно использовать как любое другое выражение — присвоить переменной, передать в качестве аргумента, напечатать, прибавить к чему-то ещё.
Инструкция return
return делает две вещи: немедленно останавливает метод и отправляет значение обратно вызывающему.
public static int absolute(int n) {
if (n < 0) {
return -n;
}
return n;
}Как только выполняется return -n, метод окончен — второй return n не выполняется. Метод с типом возвращаемого значения, отличным от void, должен возвращать значение на каждом возможном пути выполнения; компилятор отказывается компилировать, если какой-то путь отсутствует.
Для методов void вы можете использовать голое return;, чтобы выйти раньше, но писать его в конце не обязательно:
public static void greet(String name) {
if (name == null) return; // ранний выход
System.out.println("Hello, " + name);
} // неявный return на закрывающей скобкеПараметры и аргументы
Имена в сигнатуре метода — это параметры; значения, которые вы передаёте в месте вызова, — это аргументы. Различие невелико, но его стоит понимать правильно:
public static int sum(int a, int b) { // a, b — параметры
return a + b;
}
int x = 3, y = 4;
int total = sum(x, y); // x, y — аргументыКаждый вызов получает свои собственные свежие копии параметров. Присваивание a внутри sum не меняет x в месте вызова. Глава о передаче по значению углубляется в детали.
Правила для типа возвращаемого значения
Выражение после return должно быть совместимо по присваиванию с объявленным типом возвращаемого значения — тот же тип или тип, который Java может расширить до него:
public static double half(int n) {
return n / 2.0; // int / double → double, нормально
}
public static int half(int n) {
return n / 2.0; // ОШИБКА: double нельзя неявно сузить до int
}Если вам действительно нужно сузить, выполните явное приведение: return (int)(n / 2.0);.
Методы могут вызывать другие методы
Тело метода — это обычный код, включая вызовы других методов, в том числе самого себя (см. рекурсию):
public static int square(int n) { return n * n; }
public static int sumOfSquares(int a, int b) {
return square(a) + square(b);
}Построение небольших, узконаправленных методов и их компоновка — это сердце написания читаемого Java-кода.
Где живут методы
Метод всегда живёт внутри класса. Вы не можете написать функцию верхнего уровня так, как в JavaScript или Python. Класс — это контейнер; метод — один из его членов. Так что полный файл с двумя методами выглядит так:
public class MathUtils {
public static int square(int n) {
return n * n;
}
public static int cube(int n) {
return n * n * n;
}
}Из main в том же классе вы бы вызвали их как square(5) и cube(2). Из другого класса вы бы их уточнили: MathUtils.square(5).
Проработанный пример
Что дальше
Теперь, когда вы можете объявить и вызвать метод, следующий вопрос — как данные поступают в него. Глава Параметры проходит по деталям — как аргументы выстраиваются по параметрам, какие типы разрешены и что происходит, когда вызывающий передаёт объекты против примитивов.
Практика
Какое утверждение о типе возвращаемого значения метода Java верно?