Программирование на Java

       

Вызов метода


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

// объявление метода с параметром типа long void calculate(long l) { ... }

void main() { calculate(5); }

Как видно, при вызове метода передается значение типа int, а не long, как определено в объявлении этого метода.

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

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

void calculate(long a) { ... }

void main() { calculate(new Long(5)); // здесь будет ошибка }

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

void calculate(int a) { ... }

void main() { long a=5; // calculate(a); // сужение! так будет ошибка. calculate((int)a); // корректный вызов }

Наконец, в случае расширения, компилятор осуществит приведение сам, как и было показано в примере в начале этого раздела.

Надо отметить, что, в отличие от ситуации присвоения, при вызове методов компилятор не производит преобразований примитивных значений от byte, short, char или int к byte, short или char. Это привело бы к усложнению работы с перегруженными методами. Например:

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

// объявляем перегруженные методы // с аргументами (byte, int) и (short, short) int m(byte a, int b) { return a+b; } int m(short a, short b) { return a-b; }

void main() { print(m(12, 2)); // ошибка компиляции! }

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

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

long get() { return 5; }

Хотя в выражении return указан целочисленный литерал типа int, во всех местах, где будет вызван этот метод, будет получено значение типа long. Для такого преобразования действуют те же правила, что и для присвоения значения.

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

short get(Parent p) { return 5+'A'; // приведение при возвращении значения }

void main() { long a = // приведение при присвоении значения get(new Child()); // приведение при вызове метода }



Содержание раздела