Is Java pass-by-value or pass-by-reference?

In Java, for primitive types, parameters are pass-by-value; For object types, object reference is pass-by-value, however, Java is allowed to modify object’s fields via object reference.

1. Primitive Type

No doubt, for primitive type, the parameters are pass by value.

PrimitiveExample.java

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
    }

}

Output


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

2. Object Type

2.1 The is a bit tricky. If Java is pass-by-value, why the below Apple object’s field name will be updated?

ObjectExample.java

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 + '\'' +
                '}';
    }
}

Output


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

2.2 Actually, Java is passing the apple object parameter as an object reference or we call it a pointer to the real object. The reason of apple is updated to washington is because Java is allowed to modify the object’s field name via the object reference.


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

2.3 Review the following updated example to prove that Java is passing the object reference by value.

ObjectExampleUpdate.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

    }

}

Output


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

After the updateApple() method, the apple is still fuji not gala. We can update the object reference to reference another new object like apple gala, but it won’t affect the original object apple fuji, because the object reference is pass-by-value.

3. Object Type (List)

3.1 Review another similar example and read the comments for self-explanatory.

ListExample.java

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<String> 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<String> 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]
    }

}

Output


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

References

About the Author

author image
mkyong
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

avatar