В 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) { Liststr = 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/”