class ExtensionServiceLoader {

    private static final Map<Class<?>, List<?>> EXTENSION_MAP = new ConcurrentHashMap<>();

    private ExtensionServiceLoader() { }

    /**
     * load service
     * @param clazz SPI interface
     * @return services
     * @param <T> interface class
     */
    @SuppressWarnings("unchecked")
    public static <T> List<T> get(Class<T> clazz) {
        List<T> services = (List<T>) EXTENSION_MAP.get(clazz);
        if (CollectionUtils.isEmpty(services)) {
            services = load(clazz);
            if (CollectionUtils.isNotEmpty(services)) {
                EXTENSION_MAP.put(clazz, services);
            }
        }
        return services;
    }

    /**
     * load the first service
     * @param clazz SPI interface
     * @return service
     * @param <T> interface class
     */
    public static <T> T getFirst(Class<T> clazz) {
        List<T> services = get(clazz);
        return CollectionUtils.isEmpty(services) ? null : services.get(0);
    }

    private static <T> List<T> load(Class<T> clazz) {<FILL_FUNCTION_BODY>}
}

        ServiceLoader<T> serviceLoader = ServiceLoader.load(clazz);
        List<T> services = new ArrayList<>();
        for (T service : serviceLoader) {
            services.add(service);
        }
        return services;
    
<no_super_class>