Your
public List<? extends CharSequence> transform(Set<? extends CharSequence> set)
under the compiler hood is similar to
public <T1 extends CharSequence, T2 extends CharSequence> List<T1> transform(Set<T2> set)
except instead of T1 and T2 it has names like capture#1 of ? and capture#2 of ?.
As you can see, this is a generic method that has bounds on parameters supplied by the caller, but the method you introduced in the subclass isn't generic anymore -- it doesn't receive type parameters, it has concrete types!
Now compiler sees that you try to override method(signatures of methods in JVM know nothing about generics in types supplied to them, so it would be just (Ljava/util/Set;)Ljava/util/List; in both cases), and will try to ensure, that you class still can be used in place of superclass, but it's not possible, because super class could be used as
BaseClass bc = getBaseClassFromSomewhere();
List<CharBuffer> result = bc.<CharBuffer, CharBuffer>transform(someSetOfCharBuffers);
And if your code ever tried to read Strings from the supplied Set it would fail dramatically in runtime with ClassCastException, and same would happen with consumer that tried to read CharBuffers from the list you returned.
Meanwhile, you could capture type invariants of this code, if you captured parameters of transform method explicitly in the class definition, like
public static class BaseClass<T1 extends CharSequence, T2 extends CharSequence> {
public List<T1> transform(Set<T2> set) {
return null;
}
}
public static class SubClass extends BaseClass<String, String> {
@Override
public List<String> transform(Set<String> set) {
return null;
}
}
then it would be a valid overload, because methods aren't generic anymore, and upcast of SubClass is to BaseClass<String, String>, so instances of your class could be used only at places where BaseClass<String, String> are required, but not, for example, BaseClass<CharBuffer String>.
JVM method signature stays the same, but actual types are captured in class definition, therefore compiler is assured, that it won't cause problems with casting at runtime.