所以我知道您不能“轻松地”在 Java 中创建泛型数组(但您可以创建集合)。我最近遇到了一种情况,我需要一个二维对象数组(通用的)。这是它看起来的“粗略”想法(不完整,但我试图尽可能简短):
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 是)。我知道它很丑但它确实有效并且使我不必创建其他一些“psedu-kludge”,这可能会导致类覆盖“外部”类更令人头疼。提前致谢!
这可能会使事情更容易可视化
这更接近我实际做的;当然,我意识到在 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 ();
}
}
}
最佳答案
您正在做的事情是安全的,因为您控制着未暴露的 map
。您可能应该将其设为私有(private)而不是 protected ,否则扩展类可能会错误地操作它。您可以通过转换为运行时检查来消除编译器警告,如下所示:
this.map = BaseCell[][].class.cast(Array.newInstance(BaseCell.class,
new int[] { width, height }));
然后,如果在稍后的某个时间点,代码可能以编译器警告会掩盖的不兼容方式进行更改,它至少会在构建 map
时因运行时异常而提前中断.当然请记住,泛型只是在编译时被删除。
关于java - 在 Java 中创建泛型数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5428145/