Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why declare a copy of a private field as `final`

Tags:

java

oop

final

In Efficient Java Joshua Bloch writes:

Note that a nonzero-length array is always mutable, so it is wrong for a class to have a public static final array field, or an accessor that returns such a field. If a class has such a field or accessor, clients will be able to modify the contents of the array. This is a frequent source of security holes:

// Potential security hole!
public static final Thing[] VALUES = { ... };

Beware of the fact that many IDEs generate accessors that return references to private array fields, resulting in exactly this problem. There are two ways to fix the problem. You can make the public array private and add a public immutable list:

private static final Thing[] PRIVATE_VALUES = { ... };
public static final List<Thing> VALUES =
Collections.unmodifiableList(Arrays.asList(PRIVATE_VALUES));

Alternatively, you can make the array private and add a public method that returns a copy of a private array:

private static final Thing[] PRIVATE_VALUES = { ... };
public static final Thing[] values() {
    return PRIVATE_VALUES.clone();
}

And my question is:

  • Why bother with returning a final variable - if it's just a copy ?


After all, in cases where the user wants to modify it (for her/his own use) we're actually forcing her/him to create another non-final copy, which doesn't make sense.

like image 935
Nir Alfasi Avatar asked Dec 19 '22 22:12

Nir Alfasi


1 Answers

Arrays.asList wraps the original array. It doesn't copy the data. Collections.unmodifiableList also wraps the original list rather than copying the data.

That's why you're returning an unmodifiableList wrapper, because otherwise, changes made to the list returned by Arrays.asList would write through to the original private array.

like image 194
Boann Avatar answered Dec 22 '22 10:12

Boann