If on whatever reason you cannot change the Container
class, the only solution would be:
public static void main(String[] args) {
ArrayList<Foo> barList = new ArrayList<Foo>();
barList.add(new Bar());
Container container = new Container(barList);
}
However it's a rather bad design for three reason:
- Container class enforces usage of
ArrayList
over other implementations of List
interface
- Container class enforces usage of list of
Foo
instances and doesn't accept lists of subclasses of Foo
- Container class can store any descedants of
Foo
and it is not configurable
First issue can be solved by changing ArrayList
to List
.
public class Container {
public Container(List<Foo> fooList) {
this.fooList = fooList;
}
private List<Foo> fooList;
}
Second issue can be solved by using Generics
public class Container {
public Container(List<? extends Foo> fooList) {
this.fooList = fooList;
}
private List<? extends Foo> fooList;
}
Last issue can be solved by parametrizing Container
class itself:
public class Container<T extends Foo> {
public Container(List<? extends T> fooList) {
this.fooList = fooList;
}
private List<? extends T> fooList;
}
public static void main(String[] args) {
ArrayList<Bar> barList = new ArrayList<>();
Container<Foo> container = new Container<>(barList);
}
If you want to make sure that particular list implementation will have fast O(1)
get by index operation you can only accept classes which implement both List
and RandomAccess
interfaces.
public class Container {
public <L extends List<? extends Foo> & RandomAccess> Container(L fooList) {
this.fooList = fooList;
}
private List<? extends Foo> fooList;
}