Прежде чем читать эту статью, исходя из собственного опыта и понимания, вы можете сначала подумать и выбрать метод передачи параметров функций Java:
А. Передается ли оно по значению?
Б. Передано по ссылке?
C. Частично по значению, частично по ссылке?
Правильный ответ здесь пока не будет объявлен. Мы предоставим вам возможность найти ответ самостоятельно на простом примере:
1. Сначала определите тип Value.
значение общественного статического класса {частное значение String = "значение"; общественная строка getValue () { возвращаемое значение} общественный недействительный setValue (значение строки) { this.value = значение } }
2. Напишите две функции newValue и ModifyValue: newValue будет указывать входной параметр на новый объект, а ModifyValue будет вызывать метод setValue входного параметра для изменения значения объекта.
public static void newValue(Value value) { value = new Value(); value.setValue("new value"); System.out.println("В newValue, HashCode = " + value.hashCode() + ", value = " + value.getValue()); } public static void ModifyValue(Value value) { value.setValue("новое значение"); System.out.println("В ModifyValue, HashCode = " + value.hashCode() + ", value = " + value.getValue()); }
3. Простой тестовый код
public static void main(String[] args) { Value value1 = new Value(); System.out.println("Перед изменением HashCode = " + value1.hashCode() + ", value = " + value1.getValue() ); // Укажите значение1 на новый объект Value newValue(value1); System.out.println("После изменения HashCode = " + value1.hashCode() +); ", value = " + value1.getValue() + "/n"); Value value2 = new Value(); System.out.println("Перед изменением HashCode = " + value2.hashCode() + ", value = " + value2.getValue()); // Используйте метод set объекта для изменения внутреннего значения объекта.modifyValue(value2); System.out.println("После изменения HashCode = " + value2.hashCode() + ", value = " + value2.getValue() }
4. Журнал результатов выполнения:
Перед изменением HashCode = 12677476, значение = значение. В newValue HashCode = 33263331, значение = новое значение. После изменения HashCode = 12677476, значение = значение. Перед изменением HashCode = 6413875, значение = значение. В ModifyValue HashCode = 6413875, значение = новое значение. После изменения HashCode = 6413875, значение = новое значение
5. Анализ результатов:
Приведенный выше код представляет собой очень распространенный шаблон программирования: определить | сохранить | получить значение или объект на периферии, передать объект в качестве параметра в метод и изменить свойства и поведение объекта в методе. Однако методы модификации двух методов newValue иmodifyValue различны. После вызова метода объект снаружи выглядит совсем по-другому! Как понять эту разницу? Давайте сначала рассмотрим концепции передачи по значению и передачи по ссылке:
* Передача по значению означает, что когда вы передаете аргумент функции, функция получает копию исходного значения. Следовательно, если функция изменяет параметр, изменяется только копия, а исходное значение остается неизменным.
* Передача по ссылке означает, что когда аргумент передается функции, функция получает адрес памяти исходного значения, а не копию значения. Следовательно, если функция изменяет параметр, исходное значение параметра (в вызывающем коде вне функционального блока) также изменяется.
Правильный ответ: А — функции Java передают параметры по значению!
Проанализируйте журнал:
* В первом разделе вывода журнала параметр value1 изменяется, чтобы указать на новый объект внутри метода newValue, а хэш-код и значение нового объекта выводятся. Однако после выхода из домена метода newValue никаких изменений не происходит. происходит со значением value1 в основном методе. Это соответствует определению и характеристикам передачи по значению, если оно передается по ссылке, значение value1 должно измениться после вызова метода newValue(Value value).
* Второй вывод журнала показывает, что value2 выполняет операцию setValue внутри методаmodifyValue. Хэш-код остается неизменным, но значение изменяется. После выхода из домена методаmodifyValue значение2 изменяется в основном методе. Люди, которые использовали C++, могут легко понять это явление как передачу параметров функции по ссылке! Потому что это очень похоже на передачу по ссылке в C++! А ведь именно здесь наиболее вероятно впасть в недопонимание!
Скрытый принцип, лежащий в основе различных явлений двух журналов, заключается в том, что язык Java передает параметры по значению, а объекты — по ссылке; объекты, работающие в Java, на самом деле являются ссылками на рабочие объекты, а сами объекты хранятся в «куче». и «ссылка» на объект хранится в регистре или «стеке».
Псевдокод описывает разницу между методом newValue и методомmodifyValue:
newValue{ Value_ref2 = value_ref1; // Передаем ссылку value_ref1 по значению и получаем копию value_ref1 value_obj2 = new Value(); // value_obj2 создается и инициализируется в «куче» value_ref2 -> value_obj2; // value_obj2; value_obj2 value_ref2 - >value_obj2.setValue("xxx"); // value_obj2; Значение изменено printValueObj2(); // Здесь напечатано значение obj2} EditValue{ Value_ref2 = value_ref1; // Передаем ссылку value_ref1 по значению и получаем копию value_ref1 value_ref2 ->value_obj1.setValue("xxx "); // Значение value_obj1 изменено printValueObj1(); // Здесь напечатано значение obj1}
Это достаточно ясно! Когда value1_ref1 передается в функцию в качестве параметра, копия value1_ref2 сначала копируется для использования в домене функции. В это время обе ссылки указывают на один и тот же код value_obj; в функции newObject [value = new Value(); ] Фактически, value1_ref1 указывает на новый объект value_obj2; все операции установки после этого являются операциями над новым объектом; функцияmodifyValue напрямую управляет value_obj1 через метод set, который отличается от функции newValue.
Передача параметров по значению
При вызове метода вам необходимо предоставить параметры, и вы должны предоставить их в порядке, указанном в списке параметров.
Например, следующий метод печатает сообщение n раз подряд:
public static void nPrintln(String message, int n) { for (int i = 0; i < n; i++) System.out.println(message);}
Пример В следующем примере демонстрируется эффект передачи по значению.
Эта программа создает метод, который обменивает две переменные.
public class TestPassByValue { public static void main(String[] args) { int num1 = 1; int num2 = 2; System.out.println("Перед методом замены num1 равен " + num1 + ", а num2 равен " + num2) ; // Вызов метода обмена swap(num1, num2); System.out.println("После метода обмена num1 равен " + num1 + ", а num2 — это " + num2); } /** Метод замены двух переменных*/ public static void swap(int n1, int n2) { System.out.println("/tInside метода swap"); .out.println("/t/tПеред заменой n1 равно " + n1 + " n2 равно " + n2 // Поменяем местами значения n1 и n2 int temp = n1 =; n2; n2 = temp; System.out.println("/t/tПосле замены n1 равно " + n1 + " n2 равно " + n2);
Результаты компиляции и запуска приведенного выше примера следующие:
Перед методом замены num1 равно 1, а num2 равно 2 Внутри метода замены Перед заменой n1 равно 1 n2 равно 2 После замены n1 равно 2 n2 равно 1После метода замены num1 равно 1 и num2 равно 2
Вызовите метод swap, передав два параметра. Интересно, что значения реальных параметров не меняются после вызова метода.