Incompatible types in generic return type method (Java)

user2183336 :

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
  }
}
frececroka :

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.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=170932&siteId=1