Было много споров о том, «передается ли Java по значению или по ссылке?». Что ж, давайте сделаем вывод в прошлый раз: Java передается по значению, а не по ссылке. Если бы это была передача по ссылке, мы могли бы делать подстановку объектов, как в C, но в Java мы этого сделать не можем. Мы ведь это уже знаем, верно?
1. Java передает данные по значению
Когда вы передаете объект в метод, его адрес памяти копируется по частям в новую ссылочную переменную, таким образом, оба указывают на один и тот же экземпляр. Но если вы измените ссылку внутри метода, исходная ссылка не изменится.
Если бы Java передавалась по ссылке, то это тоже изменилось бы.
Чтобы доказать это, давайте посмотрим, как происходит распределение памяти во время выполнения. Это должно разрешить малейшие сомнения, если таковые имеются. Я использую следующую программу для демонстрации концепции.
public class Foo{private String attribute;public Foo(String a){this.attribute = a;}public String getAttribute() {return attribute;}public void setAttribute(String attribute) {this.attribute = attribute;}}public class Main{public static void main(String[] args){Foo f = new Foo("f");changeReference(f); // It won't change the reference!modifyReference(f); // It will change the object that the reference variable "f" refers to!}public static void changeReference(Foo a) {Foo b = new Foo("b");a = b;}public static void modifyReference(Foo c) {c.setAttribute("c");}}
2. Анализ
Давайте рассмотрим шаг за шагом, что происходит во время выполнения приведенной выше программы:
Foo f = new Foo("f");
Этот оператор создаст экземпляр класса Foo с 'attribute', инициализированным как 'f'. Ссылка на этот созданный экземпляр присваивается переменной f;

public static void changeReference(Foo a)
При выполнении этого кода объявляется ссылка типа Foo с именем a, и ей изначально присваивается значение null.

changeReference(f);
При вызове метода changeReference() ссылка a будет присвоена объекту, который передается в качестве аргумента.

Foo b = new Foo("b"); //inside first method
Это сделает то же самое, что и на первом шаге, а именно создаст новый экземпляр Foo и присвоит его b;

a = b;
Это важный момент. Здесь у нас есть три ссылочные переменные, и когда оператор выполняется, a и b будут указывать на один и тот же экземпляр, созданный внутри метода. Примечание: f неизменен и постоянно указывает на экземпляр, на который он указывал изначально. БЕЗ ИЗМЕНЕНИЙ!!

modifyReference(Foo c);
Теперь, когда этот оператор выполняет ссылку, создается c и присваивается объекту с атрибутом «f».

c.setAttribute("c");
Это изменит атрибут объекта, на который указывает ссылка c, и того же объекта, на который указывает ссылка f.

Надеюсь, это объяснение было достаточно ясным и поможет вам лучше понять материал, если это еще не так.