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?

4
  • 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. Commented Aug 13, 2013 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 :) Commented Aug 13, 2013 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>. Commented Aug 13, 2013 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. Commented Aug 13, 2013 at 15:08

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Okay, I understand that. Is there a good alternative to what I am trying to do, or should I parameterize, for example, NormalizedLevenstheinSim with <ResourceDescriptor> and in the getSim() method do an instanceof SimpleResourceDescriptor check?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.