【发布时间】:2019-02-16 04:00:41
【问题描述】:
我希望能够将枚举类型指示为接口实现,然后通过ServiceLoader API 将所有枚举加载为接口的单独实例/实现。此用例的一个示例是允许我的 API 的下游用户指定自定义值,但提供具有标准/通用实现的枚举。我的接口只需要一个字符串name(),所以任何枚举都已经实现了。
例如,Java NIO API 中的 CopyOption 接口,以及提供的 StandardCopyOption 枚举。假设我想通过ServiceLoader 将所有CopyOptions,甚至是类路径上的新内容以及标准加载到单个迭代器中(或者我愿意接受其他建议!)
我终于通过批量复制ServiceLoader 并修改它以在实例化失败时尝试使用getEnumConstants 来让它工作(try 中的部分是它目前的工作方式,catch 中的部分是什么我添加/更改):
try {
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
}
【问题讨论】:
标签: java enums serviceloader