Reputation: 655
New to Java from C++. A method with a generic return type won't compile. I think it's because I'm not specifying the type to the generic method but I don't even know how to do so. The code below does not compile saying: error: incompatible types: AnInterface cannot be converted to I ... where I is a type-variable:
To my eyes type I
sure looks compatible with the return type of get
since I explicitly declare I
to be extending AnInterface
.
import java.util.*;
interface AnInterface {
public int aMethod();
}
class AClass implements AnInterface {
AClass() { l = new ArrayList<>(); }
public int aMethod() { return 1; }
public void add(AnInterface x) { l.add(x); }
public AnInterface get() { return l.get(0); }
// method on() will not compile
public <I extends AnInterface> I on(int x) { I i = get(); return i; }
List<AnInterface> l;
}
class BClass implements AnInterface {
public int aMethod() { return 2; }
}
class Main
{
public static void main(String[] args)
{
AClass a = new AClass();
BClass b = new BClass();
a.add(b);
// How do I even call AClass::on()
// BClass x = a.on<BClass>(); // I expect to call on() like this
}
}
Upvotes: 0
Views: 92
Reputation: 1323
Take a closer look at the method on
:
public <I extends AnInterface> I on() {
I i = get();
return i;
}
Calling it with I = BClass
means get()
must return a BClass
. But the signature of get
is public AnInterface get()
, meaning we just know that it returns an AnInterface
implementation. It could be a BClass
, but it could also be anything else implementing AnInterface
.
You can change on
like this:
public AnInterface I on() {
AnInterface i = get();
return i;
}
The signature now reveals that on
returns something implementing AnInterface
, which is consistent with the type we get back from get
.
Actually your example already makes clear why the code you posted cannot type check.
AClass a = new AClass();
AClass b = new AClass();
a.add(b);
BClass c = a.<BClass>on();
We expect the call to on
to return the instance b
, since this is the first element added to a
. But b
is of type AClass
, not BClass
. If the compiler would not reject the program, we would have an instance of AClass
in the variable c
of type BClass
.
Upvotes: 3