Pola oznaczone jako final zachowują się prawie jak stałe w języku C. Prawie, gdyż owa stałość w sensie stricte dotyczy właściwie tylko typów prostych – nie można zmieniać ich wartości. Inaczej ma się sprawa z typami złożonymi – nie można zmieniać wskaźnika do wskazywanego obiektu, natomiast na obiekcie można dokonywać wszelkich dostarczanych przez niego operacji, czyli zmieniać jego stan – dodawać elementy do listy, zmieniać wartość napisu itd. Jak w poniższym przykładzie:
public class Doge { public final int primitivie = 3; public final ArrayList objectivie = new ArrayList(); //public final ArrayList objectivieNull; //Error: variable might not have been initialized public final String stringie = "Wow! Wow!"; } Doge doge = new Doge(); //doge.primitivie = 4; //Error: cannot assign a value to final variable //doge.objectivie = new ArrayList();//Error: cannot assign a value to final variable doge.objectivie.add(3);//OK! doge.stringie.toLowerCase();//OK!