As you cannot set the value of a final variable (I assume) like length of an array.
Object[] items = new Object[10];
//Not allowed
Object.length = 3;
Is it OK to use it as a read only field in your class.
It depends on what you mean by "OK". The reason you can't change items.length
is that length
is a read-only field; after an array has been created, its size is fixed. The "not allowed" line you've specified would be invalid whether items
were declared as final
or not.
It's important to understand that making items
a final
variable just means that you won't be able to change the value of the variable to refer to a different array. The variable value is a reference, not the array itself. You can't change which array the variable refers to, but you can still change the contents of the array:
// Entirely valid...
items[0] = new Object();
If you want something which is genuinely immutable, you can't use an array.
readonly in C# and final in java are more or less the same (at least when they are applied to fields). Whenever you mark a field as final the compiler won't allow you to modify its reference once assigned either through the variable initialization or through the object constructor.
However it won't prevent you from modifying the contents of the object you are referencing to, doing something like this:
public class Person {
public final String name;
public final Address address;
public Person(String name, Address address) {
this.name = name;
this.address = address;
}
}
//Someplace else
Person peter = new Person("peter", new Address("Dolphin Cove 993", "Stamford", "CT");
peter.address.state = "CA"
It is perfectly valid even when the field "address" is final.
Also, do not rely on final to build any kind of "security" or strong access restrictions to some value since it can be easily broken through reflection. (http://stackoverflow.com/questions/4516381/changing-private-final-fields-via-reflection)
All this clarification is probably not needed, but someone might find it useful
Cheers, Claudio
Some people prefer to keep all instance variables private and use "getters", e.g. a getLength()
method, but it's really personal preference. There's nothing definitively wrong with public final fields; it's just style. Personally, I use them sometimes for very simple classes.
Sure, so the way to expose it as read only would be to keep the member variable 'items' private in your class and expose a public getter method. Something like:
public int getNumItems() {
return (items == null ? 0 : items.length); //includes null handling using ternary operator
}