java关于接口的一般问题
考虑到我有一个方法,可以将列表作为参数传递。在这个方法中,我想在该列表中使用一个特定于ArrayList的函数(比如trimToSize())。处理这种问题的一般方法是什么?
这里有两个例子:
第一种方法(我认为这不好)
private void doSomething(final List<T> list) {
// ... do something
((ArrayList<T>) list).trimToSize();
// ... do something
}
第二种方法(我认为这一种更好)
private void doSomething2(final List<T> list) {
final List<T> myList = new ArrayList<T>();
// Collections.copy(myList, list); or
myList.addAll(list);
((ArrayList<T>) myList).trimToSize();
//..do something
}
我很好奇,对于这样的问题,什么是最好的解决方案
# 1 楼答案
如果您接受任何实现列表接口的对象,那么您的函数应该只调用从接口实现的方法
如果您想从ArrayList类调用函数,那么将ArrayList作为您的参数。比你的两个选择都安全
# 2 楼答案
如果只想将ArrayList作为参数,为什么不将方法声明为
private void doSomething(final ArrayList<T> list)
# 3 楼答案
那怎么办
当然,我同意Chinmay Kanchi的观点:对于私有方法来说,接受一种比必要的更通用的类型是没有意义的。我的方法只有在修改给定列表没有问题的情况下才可行
# 4 楼答案
您显示的第一个选项仅适用于
ArrayLists
,因此如果您想支持任何类型的List
,它不是一个选项。如果想支持任何类型的List
,必须将其转换(而不是强制转换)为ArrayList
我认为可能会有一些混淆,因为
List
和ArrayList
是如此紧密地联系在一起(通过继承)。这只是巧合,参数类型和我们需要调用函数的类是以这种方式关联的如果我们稍微抽象一下需求:
如果这些值是以数组的形式出现的,那么毫无疑问,只能使用数组中的值创建一个新的
ArrayList
,然后使用trimToSize(),因为强制转换不是一个选项。不幸的是,我们需要的方法trimToSize()恰好位于List
的子类上,作者希望将值作为List
传递# 5 楼答案
第二,我们有巨大的开销和大的列表,但更安全。我会选择第一个,但要检查提供的列表是否是ArrayList,然后进行演员阵容
不过,您应该有充分的理由不将ArrayList作为参数
# 6 楼答案
好的,首选的方法是首先编写一个
ArrayList
的方法。如果您需要ArrayList
特定的功能,那么该方法不需要使用List
。将确保参数类型正确的责任转移给调用者,并且不要在方法内部随意处理它