Search code examples
javaarraysfinal

Why can I edit the contents of a final array in Java?


The following code in Java uses a final array of String.

final public class Main {
  public static final String[] CONSTANT_ARRAY = {"I", "can", "never", "change"};

  public static void main(String[] args) {
    for (int x = 0; x < CONSTANT_ARRAY.length; x++) {
      System.out.print(CONSTANT_ARRAY[x] + " ");
    }
  }
}

It displays the following output on the console.

I can never change

If we try to reassign the declared final array of type String, we cause an error:

final public class Main {
  public static final String[] CONSTANT_ARRAY = {"I", "can", "never", "change"};

  public static void main(String[] args) {
    CONSTANT_ARRAY={"I", "can", "never", "change"}; //Error - can not assign to final variable CONSTANT_ARRAY.
    for (int x = 0; x < CONSTANT_ARRAY.length; x++) {
      System.out.print(CONSTANT_ARRAY[x] + " ");
    }
  }
}

Error: cannot assign to final variable CONSTANT_ARRAY.

However, the following code works:

final public class Main {
  public static final String[] CONSTANT_ARRAY = {"I", "can", "never", "change"};

  public static void main(String[] args) {
    CONSTANT_ARRAY[2] = "always";  //Compiles fine.
    for (int x = 0; x < CONSTANT_ARRAY.length; x++) {
      System.out.print(CONSTANT_ARRAY[x] + " ");
    }
  }
}

It displays

I can always change

This mean that we could manage to modify the value of the final array of type String. Can we modify the entire array in this way without violating the immutable rule of final?


Solution

  • final in Java affects the variable, it has nothing to do with the object you are assigning to it.

    final String[] myArray = { "hi", "there" };
    myArray = anotherArray; // Error, you can't do that. myArray is final
    myArray[0] = "over";  // perfectly fine, final has nothing to do with it
    

    Edit to add from comments: Note that I said object you are assigning to it. In Java an array is an object. This same thing applies to any other object:

    final List<String> myList = new ArrayList<String>():
    myList = anotherList; // error, you can't do that
    myList.add("Hi there!"); // perfectly fine.