code: public static <T> List<T> loadDeclaredClasses(
              AddOnClassLoader addOnClassLoader,
              List<String> classnames,
              Class<T> clazz,
              String type) {
          validateNotNull(addOnClassLoader, "addOnClassLoader");
          validateNotNull(classnames, "classnames");
          validateNotNull(clazz, "clazz");
          validateNotNull(type, "type");
  
          if (classnames.isEmpty()) {
              return Collections.emptyList();
          }
  
          ArrayList<T> instances = new ArrayList<>(classnames.size());
          for (String classname : classnames) {
              T instance = loadAndInstantiateClassImpl(addOnClassLoader, classname, clazz, type);
              if (instance != null) {
                  instances.add(instance);
              }
          }
          instances.trimToSize();
          return Collections.unmodifiableList(instances);
      }
docs: Loads, using the given {@code addOnClassLoader}, and creates instances with the given {@code classnames} of the
  (expected) given {@code clazz}. The {@code type} is used in error log messages, to indicate the expected type being
  loaded. Any classname that leads to an error (for example, not being of the expected type or if it was not found) it will
  be ignored (after logging the error).
  
  @param <T> the type of the class that will be instantiated
  @param addOnClassLoader the class loader of the add-on that contains the classes
  @param classnames the binary names of the classes that will be loaded
  @param clazz the type of the instance that will be created using the classes loaded
  @param type the expected type being loaded (for example, "extension", "ascanrule"...)
  @return an unmodifiable {@code List} with the instances of the given {@code clazz}
  @throws IllegalArgumentException if any of the parameters is {@code null}.
  @see #loadAndInstantiateClass(AddOnClassLoader, String, Class, String)