【发布时间】:2020-11-29 01:34:11
【问题描述】:
我有一个枚举,并希望有一个通用函数,它可以接受任何实现制造商接口的类。
public interface IComponentDataExporter { // Marker Interface }
public class ComponentsDataExporter implements IComponentDataExporter {
public ComponentTeaser populateFeatured(ComponentTeaserConfiguration componentConfig) { return null; }
}
public class BusinessComponentsDataExporter implements IComponentDataExporter { // methods }
public enum ComponentTypeEnum {
FEATURED(ComponentsDataExporter::populateFeatured);
public final BiFunction<? super IComponentDataExporter, ComponentTeaserConfiguration, ComponentTeaser> exporter;
private ComponentTypeEnum( BiFunction<? super IComponentDataExporter, ComponentTeaserConfiguration, ComponentTeaser> exporter) {
this.exporter = exporter;
}
}
我收到此编译错误The type ComponentsDataExporter does not define populateFeatured(IComponentDataExporter, ComponentTeaserConfiguration) that is applicable here
我的主要问题是BIFunction 我希望它接受ComponentsDataExporter 或BusinessComponentsDataExporter 这就是为什么我尝试使用通用通配符(?扩展IComponentDataExporter 和?超级IComponentDataExporter)。如果我用特定的类替换通配符,它工作正常。
编辑
抱歉,我的问题不清楚,所以我将尝试解释更多和更少的历史。
我想强制任何添加新枚举值的人提供一种为该组件导出数据的方法。导出方法的逻辑不能放在 Enum 中,因为它需要访问 spring 托管的 bean,并且可能有很多业务逻辑。
我已经这样做了,而且效果很好,你可以看看这个demo。
当我注意到在一个类中包含所有导出方法会太多时,我的问题就开始了,所以我决定使用不同类型的实现(BusinessComponentsDataExporter 和ComponentsDataExporter),每个实现都处理一组组件。
为了做到这一点,我添加了一个标记接口,这样我就可以标记任何导出器类,并将 Enum 中的 BiFunction 更新为具有通配符,这样它就可以接受任何类型的实现我的标记接口的对象。
BiFunction<? super IComponentDataExporter, ComponentTeaserConfiguration, ComponentTeaser> exporter
我现在正在研究的解决方案是恢复到我的旧版本 BiFunction,就像演示一样
BiFunction<ComponentsDataExporter, ComponentTeaserConfiguration, ComponentTeaser>
考虑到ComponentsDataExporter 作为外观,它具有不同类型的导出器的实例,整个导出逻辑都驻留在其中(businessExporter、contentExporter 等),因此外观将具有可以从 Enum 调用的所有高级方法。这是我现在正在考虑的解决方案的example
【问题讨论】:
-
什么是特色?
-
这是枚举值之一,这个枚举有不同的值(精选和许多其他)。我想为枚举中的每个项目设置出口商 BIFunction。
-
哦,我明白了,这太棒了。也许尝试修复您的拼写错误,看看它是否有助于解决编译错误?
this.compoenentDataExporter=componentDataExporter- 你有时会正确调用组件,有时会出现拼写错误 -
这里使用通配符没有任何意义,它们并没有改善任何东西。你必须修复你的意图的根本缺陷:你有一个没有声明任何方法的 marker 接口,但是想要使用一个假定特定方法 always 的方法引用i> 在所有实现中。但是标记接口并不能保证该方法存在。有简单的解决方案,例如如果假定所有实现都具有该方法,则在接口中声明该方法。
-
@deduper 这可能是本意,但是那样做是不可能的。您不能使用仅适用于特定实现类型的方法引用来初始化承诺处理标记接口的所有实现的函数。
标签: java generics java-8 enums functional-programming