为了账号安全,请及时绑定邮箱和手机立即绑定

枚举感知的 ServiceLoader 实现?

枚举感知的 ServiceLoader 实现?

函数式编程 2022-06-23 10:06:56
我希望能够将枚举类型指示为接口实现,然后通过ServiceLoaderAPI 将所有枚举加载为接口的单独实例/实现。此用例的一个示例是允许我的 API 的下游用户指定自定义值,但提供具有标准/通用实现的枚举。我的接口只需要一个 String name(),所以任何枚举都已经实现了它。例如,CopyOptionJava NIO API 中的接口,带有提供的StandardCopyOption枚举。假设我想将所有CopyOptions,甚至是类路径上的新 s 连同标准一起加载到单个迭代器中ServiceLoader(或者我愿意接受其他建议!)我终于通过批量复制和修改它以在实例化失败时ServiceLoader尝试使用它来工作(其中的部分是它当前的工作方式,而其中的部分是我添加/更改的部分):getEnumConstantstrycatchtry {    S p = service.cast(c.newInstance());    providers.put(cn, p);    return p;} catch (Throwable x) {    Object[] arr = c.getEnumConstants();    if (arr == null || arr.length == 0) {        fail(service, "Provider " + cn + " could not be instantiated", x);      }    List<S> list = new LinkedList<>();    for (Object o : arr) {        Enum<?> e = (Enum<?>) o;        S p = service.cast(e);        providers.put(cn + e.ordinal(), p);        list.add(p);    }    subiter = list.iterator();    return subiter.next();}我还添加了一些代码,如果subiter存在并且有下一个,则在继续下一个类名之前对其进行迭代。我的问题是:有没有更好的方法?如果最终用途不明确,现在可以通过上述修改实现:interface ImageType {    String name();}@AutoService(ImageType.class)enum StandardImageType implements ImageType {    IMAGE,    VECTOR,    RASTER,    HANDWRITING,    ICON,    LOGO,    SEAL,    RULE,    BARCODE}
查看完整描述

1 回答

?
慕慕森

TA贡献1856条经验 获得超17个赞

随着 Java 模块的引入,通过默认构造函数进行实例化的替代方法已添加到服务提供者中。但它仅在提供程序位于命名模块中时才有效。


提供者类可以声明服务类型public static T provider()所在的方法。T然后,提供者实现类甚至不需要实现或扩展T自身。


由于数组和泛型类型List<ImageType>都不能用作服务类型,因此我们需要另一种类型来潜在地封装多个实际实例,例如


package somemodule;


import java.util.function.Supplier;


public interface ImageType {

    String name();

    interface ImageTypes extends Supplier<ImageType[]> {}

}


package somemodule;


public enum StandardImageType implements ImageType {

    IMAGE,

    VECTOR,

    RASTER,

    HANDWRITING,

    ICON,

    LOGO,

    SEAL,

    RULE,

    BARCODE;


    public static ImageTypes provider() {

        return StandardImageType::values;

    }

}

和一个模块声明,如


module SomeModule {

    uses somemodule.ImageType.ImageTypes;

    provides somemodule.ImageType.ImageTypes with somemodule.StandardImageType;

}

允许写,例如


List<ImageType> all = ServiceLoader.load(ImageType.ImageTypes.class)

        .stream().flatMap(p -> Arrays.stream(p.get().get()))

        .collect(Collectors.toList());

模块内的某处(或任何其他带有uses somemodule.ImageType.ImageTypes;声明的模块)。


查看完整回答
反对 回复 2022-06-23
  • 1 回答
  • 0 关注
  • 144 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号