0

Java is Strictly Pass by Value. For example, if I pass an integer to a method that changes the value of it and don't return the value, the integer in the main method would not be changed.

However, when I passed an ArrayList to a method that adds items to the list, it turned out that the method changed the ArrayList in the main method.

public class test {
    public static void main(String[] args) {
        // create a array list
        ArrayList<String> item = new ArrayList<String>();
        addItems(item);
        System.out.println("Items in the main method are: ");
        for (int i = 0; i < item.size(); i++) {
            System.out.println(item.get(i));
        }
        System.out.println("\n***************************\n");
        int num = 0;
        plusOne(num);
        System.out.println("The value of num in the main method is: " + num);
    }

    //add two items to arrayList
    public static void addItems(ArrayList<String> item) {
        item.add("Item #1");
        item.add("Item #2");
        System.out.println("Items in the addItems method are: ");
        for (int i = 0; i < item.size(); i++) {
            System.out.println(item.get(i));
        }

    }

    //add one to num
    public static void plusOne(int num) {
        num = num +1;
        System.out.println("The value of num in the plusOne method is: " + num);

    }
}

Here's the output:

Items in the addItems method are: 
Item #1
Item #2
Items in the main method are: 
Item #1
Item #2

***************************

The value of num in the plusOne method is: 1
The value of num in the main method is: 0

This is confusing. why addItems() changed item while plusOne() didn't change num ? Could someone explain it? Thank you!

Leona Lee
  • 1
  • 2

4 Answers4

1

You need to differentiate between pass by value and pass by reference.

When you pass an object like an instance of your own custom class or a List instance as an argument to your method, they're passed by reference. Basically, you still have a pointer pointing to the original object and you're editing the object directly. This is why you see new items in your List.

However, in Java, primitive data types and immutable classes like String are passed by value. In other words, the num you received inside your plusOne method is NOT the same num you have outside the method. This is why you won't see your changes outside the scope of the method.

Just take a look at the documentation for String you'll see a ton of method taking in a String and return a NEW String. They won't modify the input string directly.

Mr.J4mes
  • 9,168
  • 9
  • 48
  • 90
  • In Java, objects are always _pass-by-value_. It's just the value being passed is the reference. If it was _pass-by-reference_ then calling `item = new ArrayList<>()` inside the `addItems` method would also assign the new instance to `item` inside the `main` method. However, that doesn't happen. But the copy of the reference points to the same object instance, so manipulations to the instance are visible to all references of said instance. Also, immutable objects are not special in the eyes of Java itself. – Slaw Apr 24 '19 at 04:38
0

This simply the reference (or pointer if you are familiar with C/C++).

In Java a List/ Array ... or any object has a reference, mean that Java stores them in the same memory cell.

So when you pass the object String to function addItems(), a reference still keeps for this object. And any change for the object inside the function will be affected by the variable because it stores in the same memory cell.

In the other hand, plusOne() receive param in primitive type (int/ long/ double), and it does not have a reference. So any change inside the function will not be affected.

If you change plusOne(Integer num) instead of (int num) and send the param í Integer, you will see the difference.

latumi
  • 21
  • 2
0

It is pass by value -- in this case, the value being passed is an address (Java calls these references) to a block of memory holding the array instance.

This gets assigned in your local parameter: item. When you do item.add(...), that tries to dereference -- look-up -- the object pointed to by the address in the local item -- and execute the operation (add) on it.

To illustrate that this is still pass by value, consider the following (syntax may not be completely valid):

ArrayList<String> x = null;
addItems(x);

void addItems(ArrayList<String> arr) {
   // arr will now have the null address
   // arr.add("xxx"); -> throws NullPointerException -> nothing to dereference

   // Consider another scenario, if here I do:
   arr = new ArrayList<>();

   // x outside won't see the change, because it had copied over its address, null
   // but not the "real" x symbol reference itself.
}

In the case of primitives like int, the value is the content itself, a value like 3 is series of bits copied over to the local parameter.

But for non-primitives, anything descending from Object -- you get basically addresses as the value -- until you apply the . operator, which look-up the object referenced by the variable.

Hope that makes more sense.

kva1966
  • 611
  • 6
  • 8
  • As a side note, it's worth learning about the idea of pointers -- which is what Java references are -- a very restricted, and typesafe version -- of arbitrary pointers. Most people come across pointers in C and C++, but they show up in other langs -- the key idea being they hold the address of something else. You **dereference** a pointer to get that 'something else'. – kva1966 Apr 24 '19 at 03:38
0

This is very basic concepts whether Java is pass by reference or pass by Value? to Answer that Java is pass by Value and in your case when you are passing primitive type it is being passed by a copy of that value (all primitive types are of not reference type) hence num is not changing in main method and in case of ArrayList it is being passed as a copy of the reference to addItems() method which is pointing to the same memory location.

For further understanding you can refer post from this link Is java pass by reference or pass by value

enter image description here

Deepak Singh
  • 411
  • 1
  • 5
  • 13