Generic method with interface return type
I have an interface and a value class that looks like this:
public interface ITest<T1> {
<T2> T1 test(OtherClass<T2> client);
}
Basically, he says that subtypes should implement a method test
that returns T1, no matter what is in the implementation subtype.
OtherClass:
public class OtherClass<T> {
public T contents;
}
However, when I want to write a subtype that implements test
and just returns the client instance it receives, I get compilation errors. I want to unify T1
and T2
:
public class Test<T1> implements ITest<T1> {
@Override
public <T1> T1 test(OtherClass<T1> client) { // compile error
return client.contents;
}
}
Is there a way to make this class work?
<T1>
basically tells any class "you choose what type T1 is!". This means that in this case <T1>
both OtherClass<T1>
are of the same type and the return type T1
is of the class T1
. If you rename one, you will see an error message:
@Override
public <OtherClassType> T1 test(OtherClass<OtherClassType> client) {
return client.contents; //you can't do that without casting OtherClassType to T1
}
If you can't edit the interface ITest
, the only way to compile is by casting, but you must make sure you can actually do this before doing this (because OtherClass can return any type, not necessarily a subclass of T1.
EDIT: The exact reason the compiler doesn't allow this is because you are actually restricting a method to test
only accepting certain types, while the method it overrides accepts any type.
I don't think this is valid since you are now constraining T2
like T1
in a class Test<T1>
.
You can solve this problem as follows:
public interface ITest<T1, T2> {
T1 test(OtherClass<T2> client);
}
public class OtherClass<T> {
public T contents;
}
public class Test<T1> implements ITest<T1, T1> {
@Override
public T1 test(OtherClass<T1> client) {
return client.contents;
}
}
In an interface declaration, you say that you want the function to test
accept any type (you have not specified any bounds for T2
).
In your implementation, you only accept T1
which is not a type.