これは不可能です。一般的な情報は、コンパイル時にのみ使用できます。ただし、リストのリストの正確な内容と構造は実行時までわかりません。したがって、コンパイラは、各リストに何が含まれるかについて保証することはできません。リストの構造を事前に知っている場合は、保持クラスなどを検討することをお勧めします。
class Holder<T,S> {
List<T> listOfTs;
List<S> listOfSs;
}
リストがすべて共通のスーパータイプを共有することがわかっている場合は、ワイルドカード境界を使用できます。
List<List<? extends Shape>> list = new ArrayList<List<? extends Shape>>();
list.add(new ArrayList<Circle>());
list.add(new ArrayList<Square>());
これにより、スーパータイプに従ってリストを操作できます。ワイルドカード バウンドの問題は、ワイルドカード バウンド コレクションに要素を追加できないことです。
次の点を考慮してください。
List<? extends Shape> list = new ArrayList<Circle>();
list.add(new Square());
// element is a valid shape, but not a valid circle
// contract of the original list is broken.
特定の数のジェネリックのみを使用することがわかっている場合は、それぞれが表すクラスを格納し、これを使用してリストを型安全な方法でキャストできます。
class ListHolder<T> {
private final Class<T> clazz;
private final List<T> list;
public ListHolder(Class<T> clazz) {
this.clazz = clazz;
this.list = new ArrayList<T>();
}
public boolean isCircleList() {
return this.clazz == Circle.class;
}
public List<Circle> getCircleList() {
if (!isCircleList()) {
throw new IllegalStateException("list does not contain circles");
}
return (List<Circle>) list;
}
public boolean isRectangleList() {
return this.clazz == Rectangle.class;
}
public List<Rectangle> getRectangleList() {
if (!isRectangleList()) {
throw new IllegalStateException("list does not contain rectangles");
}
return (List<Rectangle>) list;
}
public static void main(String[] args) {
ListHolder<Rectangle> rectangleListHolder = new ListHolder<Rectangle>(Rectangle.class );
List<ListHolder<? extends Shape>> list = new ArrayList<ListHolder<? extends Shape>>();
list.add(rectangleListHolder);
ListHolder<? extends Shape> shapeWildCardList = list.get(0);
List<Rectangle> rectangles = shapeWildCardList.getRectangleList();
}
}