code: public String asSignatureString() {
          StringBuilder sb = new StringBuilder();
  
          // <A extends String, Serializable, B extends List>
          if (typeParams.size() > 0) {
              sb.append(typeParams.stream()
                                  .map(PubApiTypeParam::asString)
                                  .collect(Collectors.joining(",", "<", "> ")));
          }
          sb.append(TypeDesc.encodeAsString(returnType));
          sb.append(" ");
          sb.append(identifier);
          sb.append("(");
          sb.append(paramTypes.stream()
                              .map(TypeDesc::encodeAsString)
                              .collect(Collectors.joining(",")));
          sb.append(")");
          return sb.toString();
      }
docs: the only difference being the upper bound of the return type.)