I give the value of three reference types (Integer,String,List) to a function to change it.
But only the value of List changed, but Integer and String are reference types too.
Why can't I change their values too?

public static void main(String[] args) {
        Integer i = new Integer(1);
        String s = "apple";
        List<Integer> l = new ArrayList<Integer>();
        l.add(new Integer(1));

        System.out.println("Integer: " + i);
        System.out.println("String: " + s);
        System.out.println("List: " + l);
        System.out.println("");

        setInteger(i);
        setString(s);
        setList(l);

        System.out.println("Integer: " + i);
        System.out.println("String: " + s);
        System.out.println("List: " + l);
    }

    public static void setInteger(Integer i)
    {
        i++;
    }

    public static void setString(String s)
    {
        s = "banana";
    }

    public static void setList(List l)
    {
        l.set(0,2);
    }

Output:
Integer: 1
String: apple
List: [1]

Integer: 1
String: apple
List: [2]

Java passes variables by value. You can not change the value of the original variable.
Some objects like Strings are immutable and their contents can not be changed.
The contents of objects like a List can be changed.

When you pass a value (primitive or reference) to a method Java creates a copy of that value, and that's what you are accessing inside the method. (Note that the value of a reference variable is a reference, not the object that is referred to, so only the reference is copied, not the object). This means that nothing you can possibly do to that copied value inside the method will affect the original value. That's why changing i or s in your first two methods has no effect outside the method.
What you did in the third case is totally different. The parameter l is a copy of the variable l from the main method. So your l contains a reference to the same List that the original referred to. Instead of trying to change l (as in the first 2 cases) you use l to refer to the List and call one of List's methods. The set method you call changes the state of the List object, but both the original reference variable l and the parameter l are unchanged.

Thanks for your help.
So is there no way to change the value of an Integer reference type in a void function?

That question is seriously ambiguous. ts easier if you are very careful about terminology here, especially to avoid confusing reference variables with objects.

The Integer class is immutable - it has no methods that change its state - so you can never change the value of an Integer object. (The same is true of String.)

You are free to change the value of an Integer reference variable (unless it's declared final) anytime you want. When you change it it refers to a different Integer object (or to null).

All method parameters are copies of whatever value (primitive or reference) was passed in the method call, so you can change them as much as you like, but that won't affect the original values that were passed.

This article has been dead for over six months. Start a new discussion instead.