I guess that b.append(", World") changes the value of s2, but then why don't a = b; or b = w; do the same thing? They are still assigning StringBuffer objects to StringBuffer objects, aren`t they? Please someone clear this up for me so I can sleep in peace.
To answer your query: the changes a = b; or b = w; works just local to static void func() method. But the changes b.append(", World."); are applied on actual reference and you are able to see this change from the place where you called func method.
in your method func, you have 3 references to objects. when you say
b.append(", World.");
you are saying "take the object that b points to, and change it to something else.
then, when you say
w=a; a=b; b=w;
you are saying
"make w point to what a points to"(and the actual objects remains unchanged) "make a point to what b points to"(and the actual objects remains unchanged) "make b point to what w points to"(and the actual objects remains unchanged)
you then leave the method, and all three of those references are dropped from scope, and gone.
your original references, s1 and s2, still point to the same things they've always pointed to. s2's object was changed.
Never ascribe to malice that which can be adequately explained by stupidity.