В общем случае существует два способа, которыми компьютерный язык может передавать аргументы подпрограмме.
Скачать исходники для статьи можно ниже
Первый способ — вызов по значению. При использовании этого подхода значение аргумента копируется в формальный параметр подпрограммы. Следовательно, изменения, выполненные в параметре подпрограммы, не влияют на аргумент.
Второй способ передачи аргумента — вызов по ссылке. При использовании этого подхода параметру передается ссылка на аргумент (а не его значение). Внутри подпрограммы эта ссылка используется для обращения
к реальному аргументу, указанному в вызове. Это означает, что изменения, выполненные в параметре, будут влиять на аргумент, использованный в вызове подпрограммы.
Как вы убедитесь, хотя в Java применяется передача по значению
для всех аргументов, конкретный эффект будет зависеть от того, передается ли базовый тип или ссылочный.
Когда методу передается элементарный тип, он передается по значению. Таким образом, создается копия аргумента, и все происходящее с параметром, который принимает аргумент, не оказывает влияния вне метода.
Рассмотрим следующую программу.
// Элементарные типы передаются по значению, class Test{ void meth(int i, int j) { i = i * 2; j = j / 2; } } class CallByValue { public static void main(String args[]) { Test ob = new Test(); int a = 15, b = 20; System.out.println("а и b перед вызовом: " + a + " " + b) ; ob.meth(a, b); System.out.println("а и b после вызова: " + a + " " + b) ; } }
Вывод этой программы имеет следующий вид.
а и b перед вызовом: 15 20
а и b после вызова: 15 20
Как видите, выполняемые внутри метода meth() операции не влияют на значения переменных а и b, использованных в вызове. Их значения не изменились.
При передаче объекта методу ситуация изменяется коренным образом,
поскольку по существу объекты передаются при вызове по ссылке. Следует помнить, что при создании переменной типа класса создается лишь ссылка на объект.
Таким образом, при передаче этой ссылки методу, принимающий ее параметр будет ссылаться на тот же объект, на который ссылается аргумент.
По сути, это означает, что объекты действуют, как если бы они передавались методам по ссылке. Изменения объекта внутри метода влияют на объект, использованный в качестве аргумента.
Рассмотрим такую программу:
// Объекты передаются по ссылке на них. class Test { int a, b; Test(int i, int j) { a = i; b = j; } // передача объекта void meth(Test o) { о.a = o.a * 2; о.b = о.b / 2; } } class PassObjRe { public static void main(String args[]) { Test ob = new Test(15, 20); System.out.println("ob.а и ob.b перед вызовом: " + ob.a + " " + ob.b); ob.meth(ob); System.out.println("ob.а и ob.b после вызова: " + ob.a + " " + ob.b); } }
Эта программа создает следующий вывод.
ob.a и ob.b перед вызовом: 15 20
ob.a и ob.b после вызова: 30 10
Как видите, в данном случае действия внутри метода meth() влияют на объект, использованный в качестве аргумента.