1

I get a compile error "inconvertible types" for the following code at the line (B). Conceptually, I believe it should work. First, "adapter" is of type BasicAdapter, and BetaAdapter is a subclass of that. Second, the type parameter BetaData is a subclass of AlphaData.

public class Test
{
  class AlphaData {} // base class for data

  class BetaData extends AlphaData {} // subclass for data

  class BasicAdapter<T> {} // a generic adapter

  class BetaAdapter extends BasicAdapter<BetaData> {} // adapter subclass with binding


  BasicAdapter<AlphaData> adapter = null; //(A)

  Test()
  {
    BetaAdapter ba = (BetaAdapter) adapter;  //(B)
  }
}

If I change the line marked (A) to

  BasicAdapter<BetaData> adapter = null;

it compiles. That makes sense. But I would like to figure out a way to make the original arrangement work.

Peri Hartman
  • 19,314
  • 18
  • 55
  • 101
  • You may want to check out [this question](http://stackoverflow.com/questions/18666710/why-are-arrays-covariant-but-generics-are-invariant). Also, the top answer to [this question](http://stackoverflow.com/questions/2660827/java-generics-covariance) looks relevant. – ajb Feb 26 '16 at 07:02
  • Or this one: http://stackoverflow.com/questions/2745265/is-listdog-a-subclass-of-listanimal-why-arent-javas-generics-implicitly-p?lq=1 – Thilo Feb 26 '16 at 07:07

2 Answers2

3
BasicAdapter<? extends AlphaData> adapter = null;

would work (or compile at least). And it's compatible with

BasicAdapter<? extends AlphaData> adapter = new BetaAdapter(); 
Thilo
  • 257,207
  • 101
  • 511
  • 656
  • This construct does, indeed, eliminate the compile error for this example. I'm having some residual errors in my real code which I'm trying to simplify right now. – Peri Hartman Feb 26 '16 at 07:10
  • I realized that I've substantially changed the question. So I'm marking your answer correct and submitting a new question for the residual problem. Thanks. – Peri Hartman Feb 26 '16 at 14:49
0

you are specifying that

class BetaAdapter extends BasicAdapter<BetaData> {}

that means, BasicAdapter must be of type BasicAdapter<BetaData> if you try to typecast BasicAdapter<AlphaData> to BasicAdapter<BetaData> then it will not work, because Type arguments must be compatible.

following code compiles and makes sense as we are accepting all classes of AlphaData in the BetaAdapter class as type argument.

public class Test
{
  class AlphaData {} // base class for data

  class BetaData extends AlphaData {} // subclass for data

  class BasicAdapter<T> {} // a generic adapter

//changes made in following line...
  class BetaAdapter extends BasicAdapter<AlphaData> {} // adapter subclass with binding


  BasicAdapter<AlphaData> adapter = null; //(A)

  Test()
  {
    BetaAdapter ba = (BetaAdapter) adapter;  //(B)
  }
} 
  • but (if you look at the code in the question) `class BetaData extends AlphaData` already – Thilo Feb 26 '16 at 06:59
  • That would eliminate the compile error in my example. It isn't a good solution for me, though, because it would defeat type checking in the various methods in BetaAdapter. Thanks for the idea anyway. – Peri Hartman Feb 26 '16 at 07:18