Путать, использует ли java вызов по значению или вызов по ссылке, когда передается ссылка на объект? [дубликат]
этот вопрос уже есть ответ здесь:
public class program1{
public static void main(String args[]){
java.util.Vector vc=new java.util.Vector();
vc.add("111");
vc.add("222");
functioncall(vc);
vc.add("333");
System.out.println(vc);
}
public static void functioncall(java.util.Vector vc){
vc=null;
}
}
выход вышеуказанной программы [111,222,333]. но, когда я запускаю следующую программу, вывод будет [333]. Смущен, когда мы передаем ссылку, как она работает, будь то вызов по значению или вызов по ссылке? и почему?--3-->
public class program1{
public static void main(String args[]){
java.util.Vector vc=new java.util.Vector();
vc.add("111");
vc.add("222");
functioncall(vc);
vc.add("333");
System.out.println(vc);
}
public static void functioncall(java.util.Vector vc){
vc.removeAllElements();
}
}
11 ответов
передает стоимостью ссылка.
чтобы бесстыдно украсть аналогию, которую я видел здесь некоторое время назад, представьте, что каждый идентификатор, который вы используете, - это лист бумаги с адресом, написанным на нем. Адрес указывает на дом.
вы можете изменить дом (например, добавив объекты в вектор или очистив его), но вы все еще держите тот же лист бумаги, и адрес по-прежнему приведет вас в тот же дом.
Если вы установите вектор в null, все, что вы делаете, это стирание адреса.
в этой статье объясняет это более подробно.
Java использует ссылки на объекты. Аргумент является ссылочным значением. Таким образом, это вызов по значению, где значение является ссылкой для объектов.
вы передаете vc в качестве справочной копии (всегда).
Затем делать
vc = null;
или vc = new Vector()
, вы просто изменяете ссылку из локального атрибута vc, и поэтому нормально, что основной не изменился.
Это вызов по значению. В обоих случаях вы ставите стоимостью ссылки на ссылку в аргументе метода, который является local ссылка на метод.
vc-это новая переменная, содержащая ссылку на вектор, который использовался для вызова метода. Изменение его на null не влияет на исходный вектор, поскольку эта ссылка является копией исходной векторной ссылки.
но поскольку это ссылка на исходный вектор, любая модификация вектора фактически изменяет исходный вектор. Таким образом, java всегда использует вызов по значению, здесь значение оказывается ссылкой.
Java и C-это всегда звоните по значению. Термин вызов по ссылке строго применяется к C++, где мы используем оператор & в формальном аргументе. В случае ссылок на объекты, ссылки копируются из актуальных на формальный аргумент.
язык программирования Java всегда использует вызов по значению. В Java все параметры методов вызываются по значению или передаются по значению. Кей С. Хорстман и Гарри Корнелл упомянули в своей очень известной книге "Основные основы Java Volume - I", что язык программирования Java всегда использует вызов по значению. Это означает, что метод получает копию всех значений параметров и не может изменять содержимое переменных параметров, которые передаются ему. Java использует два типа метода параметры:
- примитивные типы Java
- ссылки на объекты Java
Это выглядит очень прямо и просто, когда вы экспериментируете с передачей примитивных типов в метод, но становится неясным, когда дело доходит до передачи объектов в метод. Интересно, что когда ссылка на объект передается методу, метод получает копию ссылки на объект, и как оригинал, так и формальная копия ссылаются на один и тот же объект, поэтому внутри из метод состояние параметра объекта может быть изменено.
Следующая статья хорошо объясняет вызов по значению и вызов по ссылке.
Pass by value в java означает передачу копии передаваемого значения. Pass by reference в java означает передачу самого адреса. В Java аргументы всегда передаются по значению. Java поддерживает только pass by value.
с объектами Java сама ссылка на объект передается по значению, поэтому как исходная ссылка, так и копия параметра относятся к одному и тому же объекту Java. Примитивы Java тоже передаются по значению.
С Java "pass by reference" сама ссылка передается по значению.
Итак, вы не можете изменить саму ссылку, но вы можете изменить объект, на который указывает ссылка.
так что ваши removeAll
вызовов действует на Vector
Итак, вы видите результаты. Однако, если вы измените саму ссылку, как:
vc = null
или
vc = new Vector();
эти изменения указывают на новый (или нулевой ) объект, поэтому любые изменения после этого не будут отражены в объект в main
Java работает с "Call by Value concept". Если его стек и куча визуализируются, то java пытается найти значения любой переменной в локальной рабочей области, если ее нет в локальной, то она пытается найти в объекте, который находится в куче.
пример
class Foo
{
int x;
public void call(int x)
{
x++;
}
public static void main(String[] args)
{
Foo foo = new Foo();
foo.x = 5;
System.out.println(foo.x);
foo.call(foo.x);
System.out.println(foo.x);
}
}
выход выше программы : 5 , 5 Описание : В основном методе значение x присваивается 5 по ссылке " foo: В методе вызова есть локальная переменная с именем " x " (переданная как аргумент) в рабочее место. таким образом, его значение будет изменено только в рабочей области. когда управление из этой функции возвращается в метод main. В рабочей области main значение " x " по-прежнему равно 5.
пример
class Foo
{
int x;
public void call(int y)
{
x++;
}
public static void main(String[] args)
{
Foo foo = new Foo();
foo.x = 5;
System.out.println(foo.x);
foo.call(foo.x);
System.out.println(foo.x);
}
}
выход вышеуказанной программы был бы : 5, 6
описание : В основном методе значение x присваивается 5 по ссылке " foo: В методе вызова нет локальной переменной с именем " x " (переданной как аргумент) в рабочей области. Итак, java находит его в ссылка, через которую была вызвана функция" call "и значение" x "есть 5, метод вызова увеличивает его значение до" 6" таким образом, его значение будет изменено ссылкой, т. е. "foo". когда управление из этой функции возвращается в метод main. Теперь в рабочей области main значение " x "равно 6, потому что здесь мы напечатали" x " на ссылке foo.
Я надеюсь, что это поможет вам очистить ваши концепции.
С уважением, Сушиль Джайн!--3-->
Pass-by-value
фактический параметр (или выражение аргумента) полностью вычисляется, и полученное значение копируется в местоположение, используемое для хранения значения формального параметра во время выполнения метода/функции. Это местоположение обычно является куском памяти в стеке времени выполнения для приложения (так Java обрабатывает его), но другие языки могут выбирать хранилище параметров по-разному.
Pass-by-reference Формальный параметр просто действует как псевдоним для фактического параметра. В любое время, когда метод / функция использует формальный параметр (для чтения или записи), он фактически использует фактический параметр. Java строго pass-by-value