1

I have the following simple interface:

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

and implementations like

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

and

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

Both SimpleResourceDescriptor and LabelsCommentsResourceDescriptor extend

public abstract class ComparableResourceDescriptor
             implements ResourceDescriptor 

At runtime, I call the method

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

which will return an instance "sim" of ISimmilarityMeasure that relies on a specific instance of ResourceDescriptor.

I also create an array ResourceDescriptor[] candidates which will hold, at runtime, instances of the ResourceDescriptor type required by the specific ISimmilarityMeasure object.

However, if I try to call sim.getSim(candidates[0], candidates[1]) the compiler tells me that

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

I use eclipse and if I look at the available methods for sim, it shows me getSim(null s, null t). I do not understand why this is the case. Should it not be clear to the compiler, that getSim has to expect any ResourceDescriptor and that every object in candidates is a ResourceDescriptor and therefore allow the call? Should it not be an exception at runtime if the specific ISimmilarityMeasure expects a certain type of ResourceDescriptor but is handed a different one?

feob
  • 1,930
  • 5
  • 19
  • 31
  • Can you show some actual flow of your code. Currently what all you are saying is mixing up in my head. I can't get hold of all of them. For one thing, I can't understand the actual signature of `sim()` out there. You have shown us 3. – Rohit Jain Aug 13 '13 at 14:58
  • Since the interface ISimmilarityMeasure is generic, the signature of getSim(..) is also generic. In the interface it's getSim(T s, T t) and in NormalizedLevenstheinSim, for example, it's getSim(SimpleResourceDescriptor s, SimpleResourceDescriptor t). "sim" is an instance of ISimmilarityMeasure. The specific implementation (e.g. NormalizedLevenstheinSim or JaccardCommentsSim) is chosen at runtime. I admit, it is abit confusing :) – feob Aug 13 '13 at 15:03
  • 1
    Well, I'm talking about return type. In interface you have `double`, and then in the middle it is `ISimmilarityMeasure extends ResourceDescriptor>`. – Rohit Jain Aug 13 '13 at 15:04
  • I am sorry, this was just bad naming - the middle one (I renamed it to 'getSimInstance') is a static factory-method to get an implementation. `double getSim(T s, Tt)` is the actual computation method of the interface. – feob Aug 13 '13 at 15:08

1 Answers1

2

getSimInstance() will return an object of type ISimmilarityMeasure<X> for some type X. All we know about X is that it inherits from ResourceDescriptor. On this object, you call getSim(ResourceDescriptor, ResourceDescriptor). However, it's not expecting ResourceDescriptor parameters, it's expecting X parameters.

While an X is always a ResourceDescriptor, there's no guarantee that a ResourceDescriptor is an X, thus your compiler refuses to accept it.

BambooleanLogic
  • 7,530
  • 3
  • 30
  • 56
  • Okay, I understand that. Is there a good alternative to what I am trying to do, or should I parameterize, for example, NormalizedLevenstheinSim with and in the getSim() method do an `instanceof SimpleResourceDescriptor` check? – feob Aug 13 '13 at 15:20