The differences are
String class is overriding toString(), equals(), hashCode() of Object class, but StringBuffer only overrides toString().
String s1 = new String("abc");
String s2 = new String("abc");
System.out.println(s1.equals(s2)); // output true
StringBuffer sb1 = new StringBuffer("abc");
StringBuffer sb2 = new StringBuffer("abc");
System.out.println(sb1.equals(sb2)); // output false
String class is both Serializable as well as Comparable, but StringBuffer is only Serializable.
Set<StringBuffer> set = new TreeSet<StringBuffer>();
set.add(sb1);
set.add(sb2);
System.out.println(set); // gives ClassCastException because there is no Comparison mechanism
We can create a String object with and without new operator, but StringBuffer object can only be created using new operator.