If you don't mark the class final, it might be possible for me to suddenly make your seemingly immutable class actually mutable.
Notice, In the Mutable subclass, we've overridden the behavior of getValue to read a new, mutable field declared in my subclass. As a result, our class, which initially looks immutable, really isn't immutable (contains the instance of the mutable class).
In above scenario, we have passed Mutable object wherever an Immutable object is expected, which can lead a big trouble while execution of code because we are assuming the object is truly immutable(Problem when this object will use the key of HashMap).
Marking the base class final prevents this from happening.