Рубрики
Без рубрики

Является ли Java передачей по значению или передачей по ссылке?

– Является ли Java передачей по значению или передачей по ссылке?

В Java для примитивных типов параметры передаются по значению; Для типов объектов ссылка на объект передается по значению , однако Java разрешено изменять поля объекта с помощью ссылки на объект.

1. Примитивный Тип

Без сомнения, для примитивного типа параметры передаются по значению.

package com.mkyong;

public class PrimitiveExample {

    public static void main(String[] args) {

        int value = 1;

        System.out.println("Before updateValue(value) : " + value); // 1

        updateValue(value);

        System.out.println("After updateValue(value)  : " + value); // 1

    }

    private static void updateValue(int value) {
		// can i change the value?
        value = 100;
		System.out.println("Inside updateValue(value)  : " + value); // 100
    }

}

Выход

Before updateValue(value) : 1
Inside updateValue(value)  : 100
After updateValue(value)  : 1

2. Тип объекта

2.1 Это немного сложно. Если Java передается по значению, почему поле имя объекта Apple ниже будет обновлено?

package com.mkyong;

public class ObjectExample {

    public static void main(String[] args) {

        Apple apple = new Apple("fuji");

        System.out.println("Before updateApple(apple) : " + apple.getName()); // fuji

        updateApple(apple);

		// why the apple name is updated? pass by value? or reference?
        System.out.println("After updateApple(apple) : " + apple.getName()); // washington

    }

    private static void updateApple(Apple apple) {
        apple.setName("washington");
        System.out.println("Inside updateApple(apple)  : " + apple.getName()); // washington
    }

}

class Apple {

    String name;

    public Apple(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Apple{" +
                "name='" + name + '\'' +
                '}';
    }
}

Выход

Before updateApple(apple) : fuji
Inside updateApple(apple)  : washington
After updateApple(apple) : washington

2.2 На самом деле Java передает параметр apple object в качестве ссылки на объект, или мы называем его указателем на реальный объект. Причина обновления Apple до Вашингтон заключается в потому что Java разрешено изменять поле объекта имя через ссылку на объект .

	private static void updateApple(Apple apple) {
		// parameter : apple is an object reference to the apple fuji
        apple.setName("washington");
    }

2.3 Просмотрите следующий обновленный пример, чтобы доказать, что Java передает ссылку на объект по значению.

package com.mkyong;

public class ObjectExampleUpdate {

    public static void main(String[] args) {

        Apple apple = new Apple("fuji");

        System.out.println("Before updateApple(apple) : " + apple.getName()); // fuji

        updateApple(apple);

        System.out.println("After updateApple(apple) : " + apple.getName()); // fuji

    }

	// this apple is an object reference to apple fuji
    private static void updateApple(Apple apple) {

		// update the object reference to reference a new object apple('gala')
        apple = new Apple("gala");
		
		// whatever we modify here, only affect apple('gala'), not apple('fuji')
        System.out.println("Inside updateApple(apple)  : " + apple.getName()); // gala

    }

}

Выход

Before updateApple(apple) : fuji
Inside updateApple(apple)  : gala
After updateApple(apple) : fuji

После обновления метода Apple() яблоко по-прежнему fuji не гала . Мы можем обновить ссылку на объект, чтобы ссылаться на другой новый объект, например apple gala , но это не повлияет на исходный объект apple fuji , потому что ссылка на объект передается по значению.

3. Тип объекта (Список)

3.1 Просмотрите другой аналогичный пример и прочитайте комментарии для пояснения.

package com.mkyong;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class ListExample {

    public static void main(String[] args) {

        List str = new ArrayList<>(Arrays.asList("A", "B", "C"));

        System.out.println("Before updateList() : " + str); 	// [A, B, C]

        updateList(str);

        System.out.println("After updateList : " + str); 		// [A, B, C, D]

    }

    private static void updateList(List str) {			// object reference

        // Java allows to update the Object's fields via object reference.
        str.add("D");

        // update str object reference to a new object
        str = new ArrayList<>(Arrays.asList("X", "Y", "Z"));

		// whatever we modify here only affected the new list
        str.add("1");
        
		System.out.println("Inside updateList : " + str); 		// [X, Y, Z, 1]
    }

}

Выход

Before updateList() : [A, B, C]
Inside updateList : [X, Y, Z, 1]
After updateList : [A, B, C, D]

Рекомендации

Оригинал: “https://mkyong.com/java/is-java-pass-by-value-or-pass-by-reference/”