StringBuffer is mutable according to it's design, and method append is just a method to change it's content.
What final variable means in Java is:
For object, it means you can not assign another object to this reference, but it does not stops you from invoking methods of this object.
For basic type variables(int, float, boolean etc), since there's no reference and pointer, and object method here, so it simply means you can not change value of the variable.
Take the follow codes
final ObjectA objA = new ObjectA();
You can of course invoke methods of this object like below
objA.setXXX() //legal for a final variable objA
The side effect of setXXX() method is not controlled by final keyword here.
But for the follow code
final int a = 123;
You will not be able to assign any new value to this variable as below
a = 234; //Not legal if a has been defined as a final int variable.
But if you are defining it using Integer as below
final Integer a = new Integer(123);
You will be able to invoke methods of object a as below
a.xxx()
General speaking final definition is different for object and basic variable.