So, I know that you cannot "easily" create an array of a general type in Java (but you can create collections). Recently, I came across a situation where I needed a 2-dimensional array of objects (which were Generic). Here's a “crude” idea of how it looked (not complete, but I try to be as concise as possible):
class Outer<T> { private Foo[][] foo; abstract class Foo extends Blah<T> { public List<T> getContents (); } abstract class Bar extends Foo { ... } }
So, somewhere in the code, I need an array as such:
foo = new Foo[width][height];
(which, as we know, cannot happen). However, I tried this:
foo = (Foo[][])Array.newInstance (Foo.class, new int[]{getWidth (), getHeight ()});
which was accepted by the compiler, although I had to suppress warnings. I suppose my question is: “Am I going to rob me of my kidney somewhere along the line? The foo member is never exposed (though Foo and Bar types). I know it's ugly, but it definitely works and saved from the need to create some other "psedu-kludge" I would probably be called by classes that would redefine the "outer" class for more headaches. Thanks in advance!
This can facilitate visualization.
This is closer to what I'm actually doing; Of course, there are many support methods and other logic inside the map class that I forgot for brevity.
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 { 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 (); } } }