code: private static String getCanonicalTypeName(DeclaredType declaredType) {
  		List<? extends TypeMirror> typeArguments = declaredType.getTypeArguments();
  		if (!typeArguments.isEmpty()) {
  			StringBuilder typeString = new StringBuilder(declaredType.asElement().toString());
  			typeString.append('<');
  			for (int i = 0; i < typeArguments.size(); i++) {
  				if (i > 0) {
  					typeString.append(',');
  				}
  				typeString.append('?');
  			}
  			typeString.append('>');
  
  			return typeString.toString();
  		} else {
  			return declaredType.toString();
  		}
  	}
docs: Returns a string with type parameters replaced with wildcards. This is slightly different from {@link Types#erasure(javax.lang.model.type.TypeMirror)}, which removes all
  type parameter data.
  
  For instance, if there is a field with type List&lt;String&gt;, this returns a string List&lt;?&gt;.
  
  @param declaredType
  the declared type
  @return the canonical type name