我有以下简单的界面:

public interface ISimmilarityMeasure<T extends ResourceDescriptor> {
    public double getSim(T s, T t);
}


和类似的实现

public class NormalizedLevenstheinSim implements
             ISimmilarityMeasure<SimpleResourceDescriptor> { ... }




public class JaccardCommentsSim implements
             ISimmilarityMeasure<LabelsCommentsResourceDescriptor> { ... }


SimpleResourceDescriptorLabelsCommentsResourceDescriptor都扩展

public abstract class ComparableResourceDescriptor
             implements ResourceDescriptor


在运行时,我调用该方法

public static ISimmilarityMeasure<? extends ResourceDescriptor> getSimInstance(){ }


它将返回一个依赖于ResourceDescriptor特定实例的ISimmilarityMeasure实例“ sim”。

我还创建了一个数组ResourceDescriptor[] candidates,该数组将在运行时保存特定ISimmilarityMeasure对象所需的ResourceDescriptor类型的实例。

但是,如果我尝试调用sim.getSim(candidates[0], candidates[1]),则编译器告诉我

"capture#3-of ? extends ResourceDescriptor ... is not applicable for the arguments (ResourceDescriptor ... "


我使用eclipse,如果我查看sim的可用方法,则会显示getSim(null s, null t)
我不明白为什么会这样。编译器是否应该不清楚,getSim必须期望有任何ResourceDescriptor,并且candidates中的每个对象都是ResourceDescriptor,因此允许调用?如果特定的ISimmilarityMeasure期望使用某种类型的ResourceDescriptor,但是将其交给另一个,则在运行时是否应该不是例外?

最佳答案

getSimInstance()将为某些ISimmilarityMeasure<X>类型返回X类型的对象。我们对X所了解的只是它是从ResourceDescriptor继承的。在此对象上,调用getSim(ResourceDescriptor, ResourceDescriptor)。但是,它不期望使用ResourceDescriptor参数,而期望使用X参数。

虽然X始终是ResourceDescriptor,但不能保证ResourceDescriptorX,因此编译器拒绝接受它。

关于java - Java:通用接口(interface),在运行时选择实例,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18212434/

10-10 17:02