final フィールドを使用すると、フィールド自体を変更できなくなります (他のインスタンスを「指す」ようにすることにより) が、フィールドが変更可能なオブジェクトへの参照である場合は、これを行うことを止めるものは何もありません。
public void someFunction (final Person p) {
p = new Person("mickey","mouse"); //cant do this - its final
p.setFirstName("donald");
p.setLastName("duck");
}
上記の参照 p は不変ですが、参照が指す実際の Person は変更可能です。もちろん、次のようにクラス Person を不変クラスにすることもできます。
public class Person {
private final String firstName;
private final String lastName;
public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
//getters and other methods here
}
このようなクラスは、一度作成すると、いかなる方法でも変更できません。