tags:

views:

470

answers:

5

I'm not sure what the technical term for this is, but consider an interface:

public interface SomeInterface<T> {
     public T doSomething();
}

And then a second interface:

public interface SomeRelatedInterface<T, D extends SomeInterface<T>> {
     public T doSomethingRelated(D relative);
}

Is it possible to craft the second interface to only require one generic parameter, and then have the doSomethingRelated method implicitly extract the return type in its declaration. This is not legal, but this is what I am wondering if can be done in some other means:

public interface <T> SomeRelatedInterface<D extends SomeInterface<T>> {
     public T doSomethingRelated(D relative);
}

EDIT (On posting the bounty): At this point what I am looking for on this question is the reason that the language requires this duplication. That is what has been missing from the answers until now to get one accepted.

+2  A: 
public interface SomeRelatedInterface<T> {  
    T doSomethingRelated(SomeInterface<T> relative);
}
Daniel Moura
I started out with that, but I want to be able to define a specific subclass of SomeInterface for the relative, so this doesn't solve the problem.
Yishai
A: 

See if this suit your need:

public interface SomeRelatedInterface<T> {
     public  <D extends SomeInterface<T>> T doSomethingRelated(D relative);
}
J-16 SDiZ
This doesn't allow the D to be parametrized, so it can be any implementation of SomeInterface, not a specific one.
Yishai
sorry, there are no way to do what you want.
J-16 SDiZ
+2  A: 

As the type parameters are erased at compile time, IMHO you unfortunately cannot achieve what you want without specifying T as the second type parameter, just as you did in your first example.

Daniel Schneller
I agree it may not be possible, but I don't understand what compile time erasure would have to do with it - this could still be resolved at compile time, it would seem.
Yishai
Erasure has nothing whatsoever to do with the question as it was phrased
oxbow_lakes
+1  A: 

"At this point what I am looking for on this question is the reason that the language requires this duplication"

Well, the language requires that you define 2 type parameters in your example because there are, um, 2 type parameters in the problem you describe: you wish a method to be variable in both the type T and also in the implementation of SomeInterface.

These are orthogonal considerations and hence you need more than one type parameter to represent them.

Type parameters do not of course need to be defined on a class/interface; they can be defined on a method. J-16 SDiZ's answer allows your related class/interface to have one type parameter only. The second type parameter is then declared only where it is needed, on the doSomethingRelated method

oxbow_lakes
T is really inferred from the type parameter, and my having to have it redeclared by a class using the interface seems redundant. It would work fine on a method, just not on an interface declaration, hence my question.
Yishai
A: 

Well, I started a bounty on this question, and didn't know that SO's behavior was to award someone the answer (congratulations Daniel), I thought the rep would go unrewarded and I would lose it. Oh well.

Anyway, I finally have my answer. From here:

Unfortunately, for the purposes of backwards compatibility, new Map() indicates a raw type, and therefore cannot be used for type inference.

So basically when creating a class and passing in the type parameter, type inference was disabled to leave room for the raw type. So in my case there could be some type inference but that would be a question of having a more complex different kind of type inference to handle this case, which wasn't done.

Yishai