Одно из самых больших заблуждений в языке программирования Java заключается в том, является ли Java Pass by Value или Pass by Reference .
Прежде всего, мы должны понять, что подразумевается под передачей по значению или передачей по ссылке.
Передать по значению: Значения параметров метода копируются в другую переменную, а затем скопированный объект передается, поэтому он вызывается по значению.
Передача по ссылке: Псевдоним или ссылка на фактический параметр передается методу, поэтому он называется передачей по ссылке.
Допустим, у нас есть класс Balloon, как показано ниже.
public class Balloon {
private String color;
public Balloon(){}
public Balloon(String c){
this.color=c;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
И у нас есть простая программа с универсальным методом для обмена двумя объектами, класс выглядит следующим образом.
public class Test {
public static void main(String[] args) {
Balloon red = new Balloon("Red"); //memory reference 50
Balloon blue = new Balloon("Blue"); //memory reference 100
swap(red, blue);
System.out.println("red color="+red.getColor());
System.out.println("blue color="+blue.getColor());
foo(blue);
System.out.println("blue color="+blue.getColor());
}
private static void foo(Balloon balloon) { //baloon=100
balloon.setColor("Red"); //baloon=100
balloon = new Balloon("Green"); //baloon=200
balloon.setColor("Blue"); //baloon = 200
}
//Generic swap method
public static void swap(Object o1, Object o2){
Object temp = o1;
o1=o2;
o2=temp;
}
}
Когда мы выполняем вышеуказанную программу, мы получаем следующий вывод.
red color=Red
blue color=Blue
blue color=Red
Если вы посмотрите на первые две строки вывода, ясно, что метод подкачки не сработал. Это связано с тем, что Java передается по значению, этот тест метода swap () можно использовать с любым языком программирования, чтобы проверить, передается ли он по значению или по ссылке.
Давайте шаг за шагом проанализируем выполнение программы.
Balloon red = new Balloon("Red");
Balloon blue = new Balloon("Blue");
Когда мы используем оператор new для создания экземпляра класса, экземпляр создается, и переменная содержит эталонное местоположение памяти, в которой сохранен объект. Для нашего примера, давайте предположим, что «красный» указывает на 50, а «синий» указывает на 100, и это место в памяти обоих объектов Balloon.
Теперь, когда мы вызываем метод swap (), создаются две новые переменные o1 и o2, указывающие на 50 и 100 соответственно.
Ниже приведен фрагмент кода, объясняющий, что произошло при выполнении метода swap ().
public static void swap(Object o1, Object o2){ //o1=50, o2=100
Object temp = o1; //temp=50, o1=50, o2=100
o1=o2; //temp=50, o1=100, o2=100
o2=temp; //temp=50, o1=100, o2=50
} //method terminated
Обратите внимание, что мы меняем значения o1 и o2, но они являются копиями «красного» и «синего» эталонных местоположений, поэтому на самом деле нет изменений в значениях «красный» и «синий» и, следовательно, выходной .
Если вы уже поняли это, вы легко поймете причину замешательства. Поскольку переменные являются просто ссылкой на объекты, мы запутываемся, что передаем ссылку, поэтому Java передается по ссылке. Однако мы передаем копию ссылки, и, следовательно, она передается по значению. Надеюсь, теперь все сомнения исчезнут.
Теперь давайте проанализируем foo () выполнение метода.
private static void foo(Balloon balloon) { //baloon=100
balloon.setColor("Red"); //baloon=100
balloon = new Balloon("Green"); //baloon=200
balloon.setColor("Blue"); //baloon = 200
}
Первая строка является важным, когда мы вызываем метод метод вызывается на объекте в опорном местоположении. В этот момент шар указывает на 100, и поэтому его цвет меняется на Красный.
В следующей строке всплывающая ссылка изменяется на 200, и любые дальнейшие выполняемые методы выполняются для объекта в ячейке памяти 200 и не оказывают никакого влияния на объект в ячейке памяти 100. Это объясняет третью строку вывода нашей программы печать синего цвета = красный.
Надеюсь, приведенное выше объяснение прояснит все сомнения, просто помните, что переменные являются ссылками или указателями, и их копия передается методам, поэтому Java всегда передается по значению. Было бы более понятно, когда вы узнаете о памяти кучи и стека и о том, где хранятся различные объекты и ссылки.