我正在尝试将类SomeClass
的ArrayList
转换为类Object
的ArrayList
。Object
的这个新的ArrayList
然后将被传递给一个函数。我目前已经做了以下工作:
// convert ArrayList<SomeClass> to generic ArrayList<Object>
Object[] objectArray = someClassList.toArray();
ArrayList<Object> objects = new ArrayList<Object>();
for (int i = 0; i < objectArray.length; i++) {
objects.add(objectArray[i]);
}
someFunction(objects);
public void someFunction(ArrayList<Object> objects) {
// do something with objects
}
有没有更有效或"标准"的方法来做到这一点?我做的事情一开始就是"错误的"吗?
将其转换为Object
类的ArrayList
的目的是,我创建了一个外部库来处理通用Object
s的ArrayList
。
如果您能够将函数的签名更改为采用ArrayList<? extends Object> objects
或ArrayList<?> objects
(或者更好的是List
而不是ArrayList
),则您将能够直接传递ArrayList<SomeClass>
。
ArrayList<SomeClass>
是而不是ArrayList<Object>
的原因是,ArrayList<Object>
会接受您将add()
任何类型的Object
放入其中,这是ArrayList<SomeClass>
无法做到的。另一方面,ArrayList<? extends Object>
将允许您从列表中检索元素,但不能添加元素,因此ArrayList<SomeClass>
可以安全地分配给它。
由于创建了外部库,我认为修改函数签名以接受任何类型的列表会更容易。这可以使用无边界通配符?
:来实现
public static void someFunction(List<?> objects) {
// whatever
}
然后你不需要进行任何转换就可以称之为:
public static void main(String[] args) {
List<String> words = new ArrayList<>();
someFunction(words);
}
此外,除非你有充分的理由不这样做,否则最好接受someFunction
中的任何List
,而不是将你的输入限制在ArrayList
s。这会使你的代码更灵活,将来更容易更改。
将List<SubFoo>
转换为List<Foo>
的一种简单方法是使用Collections.unmodifiableList(listOfSubFoos)
,它完全是类型安全的,并且实际上强制您不能用它做任何坏事(比如添加DifferentSubFoo
)。
可以通过两种类型转换以任意方式转换类型的类型参数:
ArrayList<SomeClass> l1 = ...;
ArrayList<Object> l2 = (ArrayList<Object>) (Object) l1;
但是,正如Aasmund Eldhuset在回答中所说:这可能不是一个好主意最好给l2
一个更合适的类型,比如ArrayList<?>
。
这段代码会给您一个编译警告,说Type safetyThat: Unchecked cast from Object to ArrayList<Object>
是有原因的。例如,如果将String
添加到l2
,然后有人读取l1
并期望SomeClass
,则他们将得到非常意外的ClassCastException
。