Creando matrices de tipos genéricos en Java

Así que sé que no puedes "fácilmente" crear una matriz de un tipo genérico en Java (pero puedes crear colecciones). Recientemente me encontré con una situación en la que necesitaba una matriz bidimensional de objetos (que eran genéricos). Aquí hay una idea "aproximada" de cómo se veía (no completa pero estoy tratando de ser lo más breve posible):

class Outer<T> {
  private Foo[][] foo;

  abstract class Foo extends Blah<T> {
    public List<T> getContents ();
  }

  abstract class Bar extends Foo {
    ...
  }
}

Así que en algún lugar del código necesitaba una matriz como tal:

foo = new Foo[width][height];

(que sabemos que no puede suceder). Sin embargo, probé esto:

foo = (Foo[][])Array.newInstance (Foo.class, new int[]{getWidth (), getHeight ()});

que el compilador aceptó aunque tuve que suprimir las advertencias. Supongo que mi pregunta es "¿Esto me va a cortar de raíz en algún momento? El miembro" foo "nunca está expuesto al exterior (aunque los tipos Foo y Bar son). Sé que es feo pero definitivamente funciona y me salvó de tener que crear algún otro "psedu-kludge" que probablemente habría causado que las clases anularan los dolores de cabeza de la clase "Exterior". ¡Gracias de antemano!

Esto podría facilitar las cosas para visualizar

Esto está más cerca de lo que realmente estoy haciendo; dándome cuenta, por supuesto, de que hay muchos métodos de soporte y otra lógica dentro de la clase Map que he omitido por brevedad.

    import java.lang.reflect.Array;
    import java.util.ArrayList;
    import java.util.List;

    interface Cell<T> {
        public void add (T t);
        public boolean remove (T t);
        public List<T> getAll ();
        public Map<T> getMap ();
    }

    class Map<T> {
        protected   BaseCell    map[][];

        public abstract class BaseCell implements Cell<T> {
            private List<T> contents;

            public BaseCell () {
                this.contents = new ArrayList<T> ();
            }

            public void add (T t) {
                this.contents.add (t);
            }

            public boolean remove (T t) {
                return this.contents.remove (t);
            }

            public List<T> getAll () {
                return this.contents;
            }

            public Map<T> getMap () {
                return Map.this;
            }

            abstract public boolean test ();
        }

        public class SpecialCell extends BaseCell {
            @Override
            public boolean test() {
                return true;
            }
        }

        public class SpecialCell2 extends BaseCell {
            @Override
            public boolean test() {
                return false;
            }
        }

        @SuppressWarnings("unchecked")
        public Map (int width, int height) {
            this.map = (BaseCell[][])Array.newInstance(BaseCell.class, new int[] {width, height});
            for (int y = 0; y < height; y++) {
                for (int x = 0; x < width; x++) {
                    if (Math.random() < .5) {
                        this.map[x][y] = new SpecialCell ();
                    } else {
                        this.map[x][y] = new SpecialCell2 ();
                    }
                }
            }
        }

        public BaseCell getCellAt (int x, int y) {
            return this.map[x][y];
        }
    }

    public class Junk {

        /**
         * @param args
         */
        public static void main(String[] args) {
            class Occupant {
            }

            Map<Occupant> map = new Map<Occupant> (50, 50);
            map.getCellAt(10, 10).add(new Occupant ());

            map.getCellAt(10, 10).getMap ();

            for (int y = 0; y < 50; y++) {
                for (int x = 0; x < 50; x++) {
                    System.out.print (map.getCellAt (x, y).test () ? "1" : "0");
                }
                System.out.println ();
            }
        }
    }

Respuestas a la pregunta(5)

Su respuesta a la pregunta