3

I have an abstract class with generic (T1) that extends my Filterable interface:

public abstract class AbstractAdapter < T1 extends Filterable, T2 extends AbstractAdapter.Cell > extends ArrayAdapter < T1 > {

    public abstract class Cell {
        public T1 info;
        //...
    }

    public abstract void setData(T2 cell, int position);

    //...
}

And i have concrete class with method (setData) and Cell class implementations:

public class ConcreteAdapter extends AbstractAdapter < InfoClass, ConcreteAdapter.Cell > {

    public class Cell extends AbstractAdapter.Cell {
        //...
    }

    @Override
    public void setData(Cell cell, int position) {
        InfoClass info = (InfoClass)cell.info; // need to cast from Filterable to InfoClass (why?). Or i have compilation error
    }

    //...
}

So, i have ConcreteAdapter class with first generic class as InfoClass (that extends Filterable), in method setData i have Cell class object, but field "info" i see just as Filterable, not InfoClass. I think, field "info" already should be as generic type, because it declared as

T1 info;

but not

Filterable info;

Is it possible change field type from extendable to generic class without cast? Or its a bug in IDE?

4
  • Possible duplicate of Java Raw Type and generics interaction
    – Julien
    Commented May 18, 2016 at 11:01
  • 1
    It's wrong to assume that the only Cell object that can be passed to ConcreteAdapter.setData is ConcreteAdapter.Cell. What if I'm doing a virtual call on an object with static type AbstractAdapter and I pass in a different Cell object?
    – aioobe
    Commented May 18, 2016 at 11:17
  • @aioobe, you're right, but in my case these concrete adapters uses localy and they isolated from one another. Commented May 18, 2016 at 11:30
  • The compiler doesn't know that though.
    – aioobe
    Commented May 18, 2016 at 11:32

1 Answer 1

5

This is a very tricky case because the AbstractAdapter is raw in AbstractAdapter.Cell. If you specify enough types, then you don't need the cast anymore:

public abstract class AbstractAdapter < T1 extends Filterable, T2 extends AbstractAdapter<T1, T2>.Cell > extends ArrayAdapter < T1 > {
    //...
}

and

public class ConcreteAdapter extends AbstractAdapter < InfoClass, ConcreteAdapter.Cell > {

    public class Cell extends AbstractAdapter<InfoClass, ConcreteAdapter.Cell>.Cell {
        //...
    }

    @Override
    public void setData(Cell cell, int position) {
        InfoClass info = cell.info; 
    }

    //...
}

makes it work again. However, it's very complicated. I would move Cell into a top-level class if possible.

1
  • Your welcome :) The ? wildcards were bothering me so I refined the code a little. You can see on the updated answer how you can get rid of those.
    – Tamas Rev
    Commented May 18, 2016 at 11:24

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.