Итак, я знаю, что вы не можете «легко» создать массив универсального типа в Java (но вы можете создавать коллекции). Недавно я столкнулся с ситуацией, когда мне нужен двухмерный массив объектов (которые были Generic). Вот «приблизительное» представление о том, как это выглядело (не полное, но я стараюсь быть как можно более кратким):
class Outer<T> {
private Foo[][] foo;
abstract class Foo extends Blah<T> {
public List<T> getContents ();
}
abstract class Bar extends Foo {
...
}
}
Итак, где-то в коде мне понадобился массив как таковой:
foo = new Foo[width][height];
(который, как мы знаем, может не бывает). Однако я попробовал следующее:
foo = (Foo[][])Array.newInstance (Foo.class, new int[]{getWidth (), getHeight ()});
, который компилятор принял, хотя мне пришлось подавить предупреждения. Я предполагаю, что мой вопрос: «Неужели это когда-нибудь задушит меня в зародыше? Член« foo »никогда не подвергается воздействию извне (хотя есть типы Foo и Bar). Я знаю, что это некрасиво, но определенно работает и избавил меня от необходимости создавать какой-то другой "псевдо-кладж", который, вероятно, вызвал бы больше головной боли у классов, перекрывающих класс "Внешний". Заранее спасибо!
Это ближе к тому, что я делаю на самом деле; понимая, конечно, что есть много методов поддержки и другой логики внутри класса Map, которые я оставил для краткости.
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 ();
}
}
}