0

I defined static final ArrayList and then I've send it to other class to be changed. But it should change only locally in the second class due to he is final, like the int in my example. Why is it changed in the Main class also?

Small code example:

public class Main {

    private static final ArrayList<String> myList = new ArrayList<>(Arrays.asList("One", "Two"));
    private static final int num = 5;

    public static void main(String[] args) {

        SecondClass second = new SecondClass(myList,num);
        System.out.println("List in Main: "+myList.get(0));
        System.out.println("Num in Main: "+num);
    }
}

public class SecondClass {

    public SecondClass(ArrayList<String> list, int num)
    {
       list.set(0,"Three");
       num = 10;

        System.out.println("List in second: "+list.get(0));
       System.out.println("Num in Second: "+num);
    }
}

My output:

List in second: Three
Num in Second: 10
List in Main: Three
Num in Main: 5

What I expected it to be:

List in second: Three
Num in Second: 10
List in Main: One
Num in Main: 5
Dim
  • 4,527
  • 15
  • 80
  • 139
  • `Num in Second` is a local variable bound to the parameter reference, not the static one set by the other class. The list on the other hand, is an object reference and thus the same – OneCricketeer Jun 18 '17 at 13:53
  • 1
    As an exercise, try `SecondClass(ArrayList list, final Integer num)` – OneCricketeer Jun 18 '17 at 13:57

2 Answers2

3

myList is immutable; the object it points to is not. Use Collections.unmodifiableList() (or something like Guava's ImmutableList) if you want the list's contents to be immutable.

(And it's bad form to use ArrayList in method signatures. Just use List, or RandomAccessList if you have a really good reason to need that behavior [you don't].)

chrylis -cautiouslyoptimistic-
  • 75,269
  • 21
  • 115
  • 152
1

The final keyword prevents the myList variable from being assigned another value, but it does not prevent changes to the list instance itself.

What you need is a list that cannot be modified. So you can use an unmodifiable list:

private static final ArrayList<String> myList =     
        Collections.unmodifiableList(Arrays.asList("One", "Two"));
ernest_k
  • 44,416
  • 5
  • 53
  • 99