我正在尝试将ArrayList
课程SomeClass
转换为课程ArrayList
的{{1}}。然后,Object
的新ArrayList
将传递给函数。我目前做了以下事情:
Object
这样做有效还是“标准”?我首先做的是“错误”吗?
将其转换为// 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
}
类ArrayList
的目的是我创建了一个外部库来处理通用Object
的{{1}}。
答案 0 :(得分:5)
如果您能够将功能的签名更改为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>
将允许您从列表中检索元素,但不能添加元素,因此可以安全地为其分配{{1}}。
答案 1 :(得分:1)
由于您创建了外部库,我认为修改函数签名以接受任何类型的列表会更容易。这可以使用unbounded wildcard ?
:
public static void someFunction(List<?> objects) {
// whatever
}
然后,您不需要进行任何转换即可调用它:
public static void main(String[] args) {
List<String> words = new ArrayList<>();
someFunction(words);
}
此外,除非您有充分理由不这样做,否则最好接受List
中的任何someFunction
,而不是将您的输入限制为ArrayList
。这使您的代码在未来更灵活,更容易更改。
答案 2 :(得分:0)
可以使用两个强制转换以任意方式转换类型的类型参数:
ArrayList<SomeClass> l1 = ...;
ArrayList<Object> l2 = (ArrayList<Object>) (Object) l1;
但是,正如Aasmund Eldhuset在他的回答中所说:这可能不是一个好主意!最好给l2
更合适的类型,比如{{1} }}
此代码为您提供编译警告,说明ArrayList<?>
有原因。例如,如果将Type safetyThat: Unchecked cast from Object to ArrayList<Object>
添加到String
,然后某人阅读l2
并期望l1
他们将获得非常意外的SomeClass
。
答案 3 :(得分:0)
将List<SubFoo>
转换为List<Foo>
的简单方法是使用Collections.unmodifiableList(listOfSubFoos)
,这是完全类型安全的,并且实际上强制您不能做任何不好的事情(比如添加DifferentSubFoo
)。