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

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

Аналогично, третья пара различается лишь модификаторами доступа, что также недопустимо.

Наконец, завершает заголовок метода throws -выражение. Оно применяется для корректной работы с ошибками в Java и будет подробно рассмотрено в соответствующей лекции.

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

public final java.awt.Point

createPositivePoint(int x, int y)

throws IllegalArgumentException {

return (x>0 && y>0) ?

new Point(x, y) : null;

}

Далее, после заголовка метода следует тело метода. Оно может быть пустым и тогда записывается одним символом "точка с запятой". Native - методы всегда имеют только пустое тело, поскольку настоящая реализация написана на другом языке.

Обычные же методы имеют непустое тело, которое описывается в фигурных скобках, что показано в многочисленных примерах в этой и других лекциях. Если текущая реализация метода не выполняет никаких действий, тело все равно должно описываться парой пустых фигурных скобок:

public void empty() {}

Если в заголовке метода указан тип возвращаемого значения, а не void, то в теле метода обязательно должно встречаться return -выражение. При этом компилятор проводит анализ структуры метода, чтобы гарантировать, что при любых операторах ветвления возвращаемое значение будет сгенерировано. Например, следующий пример является некорректным:

// пример вызовет ошибку компиляции

public int get() {

if (condition) {

return 5;

}

}

Видно, что хотя тело метода содержит return -выражение, однако не при любом развитии событий возвращаемое значение будет сгенерировано. А вот такой пример является верным:

public int get() {

if (condition) {

return 5;

}

else {

return 3;

}

}

Конечно, значение, указанное после слова return, должно быть совместимо по типу с объявленным возвращаемым значением (это понятие подробно рассматривается в лекции 7).

В методе без возвращаемого значения (указано void ) также можно использовать выражение return без каких-либо аргументов. Его можно указать в любом месте метода и в этой точке выполнение метода будет завершено:

public void calculate(int x, int y) {

if (x<=0 || y<=0) {

return;

// некорректные входные

// значения, выход из метода

}

... // основные вычисления

}

Выражений return (с параметром или без для методов с/без возвращаемого значения) в теле одного метода может быть сколько угодно. Однако следует помнить, что множество точек выхода в одном методе может заметно усложнить понимание логики его работы.

Объявление конструкторов

Формат объявления конструкторов похож на упрощенное объявление методов. Также выделяют заголовок и тело конструктора. Заголовок состоит, во-первых, из модификаторов доступа (никакие другие модификаторы недопустимы). Во-вторых, указывается имя класса, которое можно расценивать двояко. Можно считать, что имя конструктора совпадает с именем класса. А можно рассматривать конструктор как безымянный, а имя класса – как тип возвращаемого значения, ведь конструктор может породить только объект класса, в котором он объявлен. Это исключительно дело вкуса, так как на формате объявления никак не сказывается:

public class Human {

private int age;

protected Human(int a) {

age=a;

}

public Human(String name, Human mother,

Human father) {

age=0;

}

}

Как видно из примеров, далее следует перечисление входных аргументов по тем же правилам, что и для методов. Завершает заголовок конструктора throws-выражение (в примере не использовано, см. лекцию 10 "Исключения"). Оно имеет особую важность для конструкторов, поскольку сгенерировать ошибку – это для конструктора единственный способ не создавать объект. Если конструктор выполнился без ошибок, то объект гарантированно создается.

Тело конструктора пустым быть не может и поэтому всегда описывается в фигурных скобках (для простейших реализаций скобки могут быть пустыми).

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

Тело конструктора может содержать любое количество return -выражений без аргументов. Если процесс исполнения дойдет до такого выражения, то на этом месте выполнение конструктора будет завершено.

Перейти на страницу:

Похожие книги