Методы Java

В предыдущих главах мы часто использовалиSystem.out.println(), так что же это такое?

  • println() — это метод.
  • System — это системный класс.
  • out — это объект стандартного вывода.

Этот оператор используется для вызова метода println() в объекте стандартного вывода out системного класса System.

Итак, что такое метод?

Метод Java — это набор операторов, которые вместе выполняют некоторую функцию.

  • Метод — это упорядоченная комбинация шагов для решения класса задач.
  • Метод содержится в классе или объекте.
  • Метод создаётся в программе, а на него ссылаются в другом месте.

Преимущества методов

  • 1. Это делает программу короче и понятнее.
  • 2. Это полезно для сопровождения программы.
  • 3. Это может повысить эффективность разработки программы.
  • 4. Это улучшает повторное использование кода.

Правила именования методов

  • 1. Первое слово имени метода должно начинаться со строчной буквы, а последующие слова — с заглавной, без использования разделителей. Например:addPerson。
  • 2. Подчёркивания могут появляться в именах тестовых методов JUnit для разделения логических компонентов имени. Типичный шаблон:test<MethodUnderTest>_<state>, напримерtestPop_emptyStack。

Определение метода

В общем случае определение метода включает следующий синтаксис:

модификатор тип возвращаемого значения имя метода(тип параметра имя параметра){... тело метода ...returnreturn value;}

Метод состоит из заголовка метода и тела метода. Ниже перечислены все части метода:

  • Модификаторы:Модификаторы необязательны и указывают компилятору, как вызывать метод. Они определяют тип доступа к методу.
  • Тип возвращаемого значения:Метод может возвращать значение. returnValueType — это тип данных значения, возвращаемого методом. Некоторые методы выполняют требуемую операцию, но не возвращают значение. В этом случае returnValueType — это ключевое словоvoid。
  • Имя метода:Это фактическое имя метода. Имя метода и таблица параметров вместе составляют сигнатуру метода.
  • Тип параметра:Параметры действуют как заполнители. При вызове метода параметру передаётся значение. Это значение называется фактическим аргументом или переменной. Список параметров определяет типы параметров, порядок и количество параметров. Параметры необязательны; метод может не содержать параметров.
  • Тело метода:Тело метода содержит конкретные операторы, определяющие функциональность метода.

Например:

public static int age(int birthday){...}

Может быть несколько параметров:

static float interest(float principal, int year){...}

Примечание:В некоторых других языках методы называются процедурами и функциями. Метод, возвращающий значение, отличное от void, называется функцией; метод, возвращающий значение void, называется процедурой.

Пример

Следующий метод содержит 2 параметра, num1 и num2, и возвращает максимум из этих двух параметров.

/** Возвращает большее значение из двух целочисленных переменных*/ public static int max(int num1, int num2) { int result; if (num1 > num2) result = num1; else result = num2; return result; }

Более краткий способ записи (тернарный оператор):

public static int max(int num1, int num2) { return num1 > num2 ? num1 : num2; }

Вызов метода

Java поддерживает два способа вызова метода, в зависимости от того, возвращает ли метод значение.

Когда программа вызывает метод, управление программой передаётся вызываемому методу. Управление возвращается программе, когда вызываемый метод выполняет оператор return или достигает закрывающей фигурной скобки тела метода.

Когда метод возвращает значение, вызов метода обычно рассматривается как значение. Например:

int larger = max(30, 40);

Если метод возвращает void, вызов метода должен быть оператором. Например, метод println возвращает void. Следующий вызов является оператором:

System.out.println("Добро пожаловать в Example!");

Пример

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

Код файла TestMax.java:

public class TestMax { /** Главный метод*/ public static void main(String[] args) { int i = 5; int j = 2; int k = max(i, j); System.out.println( i + "и" + j + "Сравните, максимальное значение:" + k); } /** Возвращает большее из двух целочисленных переменных*/ public static int max(int num1, int num2) { int result; if (num1 > num2) result = num1; else result = num2; return result; } }

Приведённый выше пример компилируется и выполняется со следующим результатом:

5 和 2 比较,最大值是:5

Эта программа содержит метод main и метод max. Метод main вызывается JVM. Помимо этого, метод main ничем не отличается от других методов.

Заголовок метода main фиксирован, как показано в примере. Он имеет модификаторы public и static, возвращает значение void, имя метода — main, и он принимает параметр типа String[]. String[] указывает, что параметр является массивом строк.


Ключевое слово void

В этом разделе объясняется, как объявить и вызвать метод void.

Следующий пример объявляет метод с именем printGrade и вызывает его для вывода заданной оценки.

Пример

Код файла TestVoidMethod.java:

public class TestVoidMethod { public static void main(String[] args) { printGrade(78.5); } public static void printGrade(double score) { if (score >= 90.0) { System.out.println('A'); } else if (score >= 80.0) { System.out.println('B'); } else if (score >= 70.0) { System.out.println('C'); } else if (score >= 60.0) { System.out.println('D'); } else { System.out.println('F'); } } }

Приведённый выше пример компилируется и выполняется со следующим результатом:

C

Здесь метод printGrade — это метод типа void; он не возвращает значение.

Вызов void-метода должен быть оператором. Поэтому он вызывается как оператор в третьей строке метода main, точно так же, как любой оператор, заканчивающийся точкой с запятой.


Передача параметров по значению

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

Например, следующий метод выводит сообщение n раз подряд:

Код файла TestVoidMethod.java:

public static void nPrintln(String message, int n) { for (int i = 0; i < n; i++) { System.out.println(message); } }

Пример

Следующий пример демонстрирует эффект передачи по значению.

Программа создаёт метод, который меняет местами две переменные.

Код файла TestPassByValue.java:

public class TestPassByValue { public static void main(String[] args) { int num1 = 1; int num2 = 2; System.out.println("Перед обменом значение num1 равно:" + num1 + ", а значение num2 равно:" + num2); //Вызов метода swap swap(num1, num2); System.out.println("После обмена значение num1 равно:" + num1 + ", а значение num2 равно:" + num2); } /** Метод для обмена двух переменных*/ public static void swap(int n1, int n2) { System.out.println("\tВход в метод swap"); System.out.println("\t\tПеред обменом значение n1 равно:" + n1 + ", значение n2:" + n2); //Обмен значениями n1 и n2 int temp = n1; n1 = n2; n2 = temp; System.out.println("\t\tПосле обмена значение n1 равно" + n1 + ", значение n2:" + n2); } }

Приведённый выше пример компилируется и выполняется со следующим результатом:

交换前 num1 的值为:1 ,num2 的值为:2
    进入 swap 方法
        交换前 n1 的值为:1,n2 的值:2
        交换后 n1 的值为 2,n2 的值:1
交换后 num1 的值为:1 ,num2 的值为:2

Передайте два аргумента, чтобы вызвать метод swap. Интересно, что после вызова метода значения фактических аргументов не изменяются.


Перегрузка методов

Использованный выше метод max работает только с данными типа int. Но что, если вы хотите получить максимум из двух данных типа с плавающей точкой?

Решение — создать другой метод с тем же именем, но другими параметрами, как показано в следующем коде:

public static double max(double num1, double num2) { if (num1 > num2) return num1; else return num2; }

Если при вызове метода max вы передаёте параметры типа int, будет вызван метод max с параметрами типа int;

Если передаются параметры типа double, будет вызвано тело метода max с типом double. Это называется перегрузкой методов;

То есть два метода класса имеют одинаковое имя, но разные списки параметров.

Компилятор Java определяет, какой метод следует вызвать, на основе сигнатуры метода.

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

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


Область видимости переменных

Область видимости переменной — это часть программы, в которой можно ссылаться на переменную.

Переменные, определённые внутри метода, называются локальными переменными.

Область видимости локальной переменной начинается с её объявления и продолжается до конца блока, который её содержит.

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

Область видимости параметров метода охватывает весь метод. Параметры фактически являются локальными переменными.

Переменные, объявленные в части инициализации цикла for, имеют область видимости, охватывающую весь цикл.

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

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

Использование аргументов командной строки

Иногда вы хотите передать сообщения программе при её запуске. Это достигается путём передачи аргументов командной строки в функцию main().

Аргументы командной строки — это информация, которая следует за именем программы при её выполнении.

Пример

Следующая программа выводит все аргументы командной строки:

Код файла CommandLine.java:

public class CommandLine { public static void main(String[] args){ for(int i=0; i<args.length; i++){ System.out.println("args[" + i + "]: " + args[i]); } } }

Запустите эту программу следующим образом:

$ javac CommandLine.java 
$ java CommandLine this is a command line 200 -100
args[0]: this
args[1]: is
args[2]: a
args[3]: command
args[4]: line
args[5]: 200
args[6]: -100

Методы-конструкторы

Конструктор — это специальный метод, используемый для создания объектов класса. Когда объект создаётся с помощью ключевого слова new, конструктор автоматически вызывается для инициализации свойств объекта.

Характеристики конструктора:

  • Имя метода совпадает с именем класса: Имя конструктора должно совпадать с именем класса.
  • Нет возвращаемого типа: У конструкторов нет возвращаемого типа; дажеvoidvoid нельзя писать.
  • Автоматически вызывается при создании объекта: Каждый раз, когда вы используетеnewnew для создания объекта, конструктор вызывается автоматически.
  • Можно перегружать: Вы можете определить несколько конструкторов для одного и того же класса, но списки параметров этих конструкторов должны различаться (то есть они образуют перегрузку).

Независимо от того, определяете ли вы собственный конструктор, у всех классов есть конструкторы, потому что Java автоматически предоставляет конструктор по умолчанию. Модификатор доступа конструктора по умолчанию совпадает с модификатором доступа класса (если класс public, конструктор тоже public; если класс изменён на protected, конструктор тоже изменён на protected).

Как только вы определите собственный конструктор, конструктор по умолчанию становится недействительным.

Пример

Ниже приведён пример использования конструктора:

//Простой конструктор class MyClass { int x; //Ниже приведён конструктор MyClass(int i ) { x = i; } }

Вы можете вызвать конструктор, чтобы инициализировать объект следующим образом:

Код файла ConsDemo.java:

public class ConsDemo { public static void main(String[] args) { MyClass t1 = new MyClass( 10 ); MyClass t2 = new MyClass( 20 ); System.out.println(t1.x + " " + t2.x); } }

Результат выполнения выглядит следующим образом:

10 20

Для получения дополнительной информации обратитесь к следующей главе:Конструкторы Java:。

Аргументы переменной длины

Начиная с JDK 1.5, Java поддерживает передачу аргументов переменной длины одного и того же типа в метод.

Объявление аргументов переменной длины метода выглядит следующим образом:

typeName... parameterName

В объявлении метода добавьте многоточие (...) после указанного типа параметра.

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

Пример

Код файла VarargsDemo.java:

public class VarargsDemo { public static void main(String[] args) { //Вызов метода с переменным числом аргументов printMax(34, 3, 3, 2, 56.5); printMax(new double[]{1, 2, 3}); } public static void printMax( double... numbers) { if (numbers.length == 0) { System.out.println("Аргумент не передан"); return; } double result = numbers[0]; for (int i = 1; i < numbers.length; i++){ if (numbers[i] > result) { result = numbers[i]; } } System.out.println("Максимальное значение равно " + result); } }

Приведённый выше пример компилируется и выполняется со следующим результатом:

The max value is 56.5
The max value is 3.0

Метод finalize()

Метод finalize объявлен устаревшим в Java 9 и будет удалён в будущих версиях Java. Рекомендуется использовать try-with-resourcestry-with-resourcesилиjava.lang.ref.Cleanerдля управления ресурсами.

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

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

В методе finalize() необходимо указать операции, которые должны быть выполнены при уничтожении объекта.

Общий формат finalize() таков:

protected void finalize() { //Здесь размещается код завершения. }

Ключевое слово protected — это модификатор, который гарантирует, что метод finalize() не будет вызван кодом вне класса.

Конечно, освобождение памяти в Java может выполняться автоматически JVM. Если вы хотите использовать его вручную, вы можете использовать вышеуказанный метод.

Пример

Код файла FinalizationDemo.java:

public class FinalizationDemo { public static void main(String[] args) { Cake c1 = new Cake(1); Cake c2 = new Cake(2); Cake c3 = new Cake(3); c2 = c3 = null; System.gc(); //Вызов сборщика мусора Java } } class Cake extends Object { private int id; public Cake(int id) { this.id = id; System.out.println("Cake Object " + id + "создан"); } protected void finalize() throws java.lang.Throwable { super.finalize(); System.out.println("Cake Object " + id + "удалён"); } }

При запуске приведённого выше кода результат вывода будет следующим:

$ javac FinalizationDemo.java 
$ java FinalizationDemo
Cake Object 1is created
Cake Object 2is created
Cake Object 3is created
Cake Object 3is disposed
Cake Object 2is disposed

Альтернатива:Рекомендуется использовать интерфейс AutoCloseable вместе с оператором try-with-resources для автоматического закрытия ресурсов. Например:

try (Resource res = new Resource()) {
    // 使用资源
} catch (Exception e) {
    e.printStackTrace();
}
Другие расширения