Поиск по сайту:

Java передается по значению, а не по ссылке


Введение

Многие Java-программисты задаются вопросом, является ли Java передачей по значению или передачей по ссылке. В этой статье кратко изложено, почему Java всегда передается по значению.

Во-первых, что означает передача по значению и передача по ссылке?

  • Передача по значению: значения параметров метода копируются в другую переменную, а затем скопированный объект передается методу. Метод использует копию.
  • Передать по ссылке: методу передается псевдоним или ссылка на фактический параметр. Метод получает доступ к фактическому параметру.

Часто путаница с этими терминами является результатом концепции ссылки на объект в Java. Технически Java всегда передается по значению, потому что даже если переменная может содержать ссылку на объект, эта ссылка на объект является значением, представляющим расположение объекта в памяти. Поэтому ссылки на объекты передаются по значению.

И ссылочные типы данных, и примитивные типы данных передаются по значению. Узнайте больше о типах данных в Java.

В дополнение к пониманию типов данных также важно понимать распределение памяти в Java, поскольку ссылочные типы данных и примитивные типы данных хранятся по-разному.

Демонстрация передачи по значению

В следующем примере показано, как значения передаются в Java.

В примере программы используется следующий класс:

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;
	}
}

В следующем примере программы используется общий метод swap(), который меняет местами две переменные. Другой метод, changeValue(), пытается изменить значения переменных.

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("After the swap method executes:");
		System.out.println("`red` color value = " + red.getColor());
		System.out.println("`blue` color value = " + blue.getColor());
		
		changeValue(blue);
		System.out.println("After the changeValue method executes:");
		System.out.println("`blue` color value = " + blue.getColor());
		
	}

	// Generic swap method
	public static void swap(Object o1, Object o2){
		Object temp = o1;
		o1 = o2;
		o2 = temp;
	}

	private static void changeValue(Balloon balloon) { // balloon = 100
		balloon.setColor("Red"); // balloon = 100
		balloon = new Balloon("Green"); // balloon = 200
		balloon.setColor("Blue"); // balloon = 200
	}

}

Когда вы выполняете пример программы, вы получаете следующий вывод:

Output
After the swap method executes: 'red' color value = Red 'blue' color value = Blue After the changeValue method executes: 'blue' color value = Red

Вывод показывает, что метод swap() не менял значения цвета исходных объектов. Это помогает показать, что Java передается по значению, поскольку метод swap() работает только с копиями исходных значений ссылки на объект.

Этот тест метода swap() можно использовать с любым языком программирования, чтобы проверить, передается ли он по значению или по ссылке.

Объяснение метода swap() в примере

Когда вы используете оператор new для создания экземпляра класса, объект создается, а переменная содержит место в памяти, где объект сохранен.

Balloon red = new Balloon("Red");
Balloon blue = new Balloon("Blue");

Вот пошаговое описание того, что происходит при выполнении метода swap():

  • Assume that red is pointing to memory location 50 and blue is pointing to memory location 100, and that these are the memory locations of both Balloon objects.

  • When the class calls the swap() method with the red and blue variables as arguments, two new object variables, o1 and o2, are created. o1 and o2 also point to memory locations 50 and 100 respectively.

  • The following code snippet explains what happens within the swap() method:

    public static void swap(Object o1, Object o2) { // o1 = 50, o2 = 100
    	Object temp = o1; // assign the object reference value of o1 to temp: temp = 50, o1 = 50, o2 = 100
    	o1 = o2; // assign the object reference value of o2 to o1: temp = 50, o1 = 100, o2 = 100
    	o2 = temp; // assign the object reference value of temp to o2: temp = 50, o1 = 100, o2 = 50
    } // method terminated
    
  • The values of o1 and o2 are swapped, but because the values are copies of the red and blue memory locations, there is no change to the values of the red and blue color values.

Поскольку переменные содержат ссылку на объекты, распространенной ошибкой является предположение, что вы передаете ссылку, а Java передается по ссылке. Однако вы передаете значение, которое является копией ссылки, и поэтому оно передается по значению.

Объяснение примера метода changeValue()

Следующий метод в примере программы изменяет значение цвета объекта, на который ссылается переменная blue:

private static void changeValue(Balloon balloon) { // balloon = 100
	balloon.setColor("Red"); // balloon = 100
	balloon = new Balloon("Green"); // balloon = 200
	balloon.setColor("Blue"); // balloon = 200
}

Вот пошаговое описание того, что происходит в методе changeValue():

  • Класс вызывает метод changeValue() для переменной blue, которая ссылается на ячейку памяти 100. Первая строка создает ссылку, которая также указывает на ячейку памяти 100. Значение цвета объект в ячейке памяти 100 изменяется на Красный.
  • Вторая строка создает новый объект (со значением цвета Green). Новый объект находится в ячейке памяти 200. Любые дальнейшие методы, выполняемые с переменной balloon, воздействуют на объект в ячейке памяти 200 и не влияют на объект в ячейке памяти 100. Новый balloon перезаписывает ссылку, созданную в строке 1, а ссылка balloon из строки 1 больше недоступна в этом методе.
  • Третья строка изменяет значение цвета нового объекта Balloon в ячейке памяти 200 на Blue, но не влияет на исходный объект, на который ссылается blue. в ячейке памяти 100. Это объясняет, почему последняя строка выходных данных примера программы выводит blue color value=Red, что отражает изменение по сравнению со строкой 1.

Заключение

В этой статье вы узнали о том, почему Java передается по значению. Продолжите свое обучение с помощью дополнительных руководств по Java.