Search code examples
javaarraysstringfinal

Is a final array of final strings still mutable?


Suppose I have an array

public static final String[] fooArray ={ Foo.a, Foo.b, Foo.c };

where Foo.a b and c are static final Strings.

Could I still do something like fooArray[0] = "taco"; and end up with { taco, Foo.b, Foo.c } as the contents of fooArray?

If so, would making the array private, and having a getter that makes a copy of the array using Arrays.copyOf solve this issue?


Solution

  • The final applies to the array reference, not its entries. Different strings can still be written to its entries.

    If so, would making the array private, and having a getter that makes a copy of the array using Arrays.copyOf solve this issue?

    Yes, defensive copies are a fairly standard way to handle this.

    Alternately, given what you've outlined, you don't need to have the array at all, just a getter that looks like this:

    public String[] getFooArray() {
        return new String[] { Foo.a, Foo.b, Foo.c };
    }
    

    Or as jtahlborn commented, use an unmodifiable List<String>:

    public static final List<String> fooArray;
    static {
        List<String> a = new ArrayList<>();
        Collections.addAll(a, Foo.a, Foo.b, Foo.c);
        fooArray = Collections.unmodifiableList(a);
    }
    // (There's probably some really nifty Java8 way to do that as a one-liner...