0

I'm trying to understand how parameters are passed in Java. For example, I have the following code:

class Runner{
    public static void main(String[] args)
    {
        Integer test = new Integer(20);
        updateObject(test);
        System.out.println(test);
    }
    public static void updateObject(Integer test)
    {
        test = 50;
    }
}

It prints "20".

However, if I use my own class instead of Integer like this:

import java.util.*;
class Test {
    int num;
    Test(int x){
        num = x;
    }
    Test(){
        num = 0;
    }
}

class Runner{
    public static void main(String[] args)
    {
        Test test = new Test(20);
        updateObject(test);
        System.out.println(test.num);
    }
    public static void updateObject(Test test)
    {
        test.num = 50;
    }
}

In this case println prints "50".

Why in the 1st case my parameter was not changed but it has been changed in the 2nd case?

  • The first example reassigns a reference within the method (makes test point to a different integer) so it has no effect outside it (the reference changed is a copy of the reference used elsewhere). The second changes an instance member of an object. This looks very similar to https://stackoverflow.com/q/40480/217324 – Nathan Hughes Sep 08 '21 at 03:34
  • Does this answer your question? [How can I change Integer value when it is an argument like change array's value?](https://stackoverflow.com/questions/26185527/how-can-i-change-integer-value-when-it-is-an-argument-like-change-arrays-value) – Deepak Patankar Sep 08 '21 at 03:36
  • 1
    Example #1 not good, Integer is immutable – 4EACH Sep 08 '21 at 03:40

1 Answers1

0

In java it is always parameters passed by value. Tricky thing if you dealing with instances of class, it is referential types, and when you passing as an argument to a method, reference to an instance pass by value, that means that reference to that object will be copied to method argument, so reference acting as value itself.

In you first example, when you doing Integer test = new Integer(), you creating new instance of integer, and setting reference of it to test variable. Tricky part here, that Integer is immutable type, even if you have reference to integer there is no legit way to change it content(it is possible with Reflection, however in most scenarios using reflection to mutate immutable is bad thing to do)

Next thing in your first example, you doing test = 50, this thing is called autobox, Integer is still immutable, and what java does here, it compiles you code as test = new Integer(50) (there are some optimization, but let’s skip them for now), so it will create new instance of integer with value 50, and overwrite variable reference of method updateObject to that new one, Integer(20) still exists somewhere in memory, however variable test in method updateObject doesn’t have reference to it anymore. However you have another test variable in method main, and this variable still keeping reference to the first instance of Integer with number 20.

Regarding your second example, you created mutable type now, and executing line: test.num = 50 - it will keep reference to instance of your class unchanged, but it will mutate fields of the class. In second example test variable in both of your static methods referencing to the same instance. That’s why it prints same value.

Hope it will make it clear.