3

我有一个PictureArrayAdapter扩展ArrayAdapter<Pair<String, ImageInitialiser>>并具有以下构造函数的类:

public PictureArrayAdaptor(Context context, Pair<String, ImageInitialiser>[] values)

我们已经明确声明,调用此构造函数时,程序员必须传递 a Pair<String, ImageInitialiser>[],否则可能会发生类型错误。现在,在没有警告的情况下生成这样的对象相当困难:

@SuppressWarnings("unchecked")
Pair<String, ImageInitialiser> tableData[] = new Pair[1];
tableData[0]=new Pair<String, ImageInitialiser>("A", new ResourceImageInitialiser(R.drawable.sample1));

一种可能性是改用列表。但是,为了保持一致性,我想保持所有构造函数与基类完全相同。有没有更好的方法来调用这个构造函数?我真的不认为这就是它应该被调用的方式。

4

3 回答 3

4

另一种方法是创建一个扩展 Pair 的类,例如

class NamedImage extends Pair<String, ImageInitialiser> { ... }
class PictureArrayAdapter extends ArrayAdapter<NamedImage> { ... }

NamedImage现在是一种可具体化的类型,因此您可以像使用数组一样NamedImage[]不受惩罚。此外,它消除了未经检查的异常并简化了所有声明,使它们不再具有嵌套类型参数。

于 2012-08-15T03:52:21.020 回答
2

数组和泛型就像油和水。使用泛型类型的数组无法保证类型安全,因此会出现警告。varargs ( ...) 也是如此,因为它涉及隐式数组创建。有关原因的详细说明,请参阅泛型常见问题解答。

我强烈建议使用参数 aList而不是数组。如果超级构造函数必须采用数组,则可以调用toArray. List一般来说,集合比数组更通用,有些人认为除非绝对必要,否则不应再直接使用数组。

于 2012-08-15T01:41:05.183 回答
0

好的,我已经考虑了一段时间,我意识到我这样做的方式正是这样做的方式。当涉及到通用对象时,列表肯定更好用,但我试图匹配一个接口以保持一致性。

泛型教程(第15 页)解释了我们不能创建泛型对象数组的原因是这将允许运行时类型错误而没有警告。

List<?>[] lsa = new List<?>[10]; // ok, array of unbounded wildcard type
Object o = lsa;
Object[] oa = (Object[]) o;
List<Integer> li = new ArrayList<Integer>();
li.add(new Integer(3));
oa[1] = li; // correct
String s = (String) lsa[1].get(0); // run time error, but cast is explicit

通过使用@SuppressWarnings("unchecked"),我们迫使任何接触此代码的人都必须考虑类型安全,而不是依赖编译器。这没什么大不了的,因为在像 Python 这样的语言中,根本没有编译时类型安全。@SuppressWarnings 让程序员清楚地知道他们必须自己管理它,但即使他们错过了这一点,它仍然可以在运行时被捕获。

现在,让我们考虑构造函数。我认为这将是编译器发出警告的好地方,因为声明泛型数组变量和泛型数组参数之间没有太大区别。在这里,我们没有@SuppressWarnings,但我仍然认为类型本身给了程序员足够的警告。此外,最好冒着有人更改这个类引入类型错误的风险,而不是让它只接受一个泛型数组并冒着任何调用者犯类型错误的风险。

于 2012-08-15T02:26:38.753 回答