关于接口的java一般问题

时间:2010-02-18 23:38:51

标签: java interface

考虑到我有一个方法可以将List作为参数传递。在这个方法中,我想在该列表中使用例如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
}

我很好奇这是什么问题的最佳解决方案。

8 个答案:

答案 0 :(得分:12)

嗯,首选方法是首先编写方法以获取ArrayList。如果您需要ArrayList特定功能,则该方法无法使用List。将确保参数属于正确类型的责任转移给调用者,并且不要在方法内乱搞它。

答案 1 :(得分:6)

如果只想将ArrayList作为参数,为什么不将方法声明为private void doSomething(final ArrayList<T> list)

答案 2 :(得分:3)

如果你接受任何实现List接口的对象,那么你的函数应该只调用从接口实现的方法。

如果要从ArrayList类调用函数,则将ArrayList作为参数。比任何一种选择都安全得多。

答案 3 :(得分:2)

第二个我们有大量列表的巨额开销,但更安全。我会去第一个,但检查提供的List是否是ArrayList,然后进行转换。

你应该有充分的理由不把ArrayList作为参数。

答案 4 :(得分:2)

您展示的第一个选项仅适用于ArrayLists,因此如果您想支持任何类型的List,则不能选择此选项。如果您想支持任何类型的List,您必须将其转换(而非转换)为ArrayList

我认为可能存在一些混淆,因为ListArrayList密切相关(通过继承)。只有巧合的是,参数类型和我们需要调用函数的类以这种方式相关。

如果我们抽象一下要求:

  1. 我们需要采取一系列价值观
  2. 我们需要使用 trimToSize() 一系列价值观。
  3. 如果值是以数组形式出现的话,那么用数组中的值创建一个新的ArrayList然后使用 trimToSize()就没有问题了,因为是一个选择。我们需要的方法 trimToSize()恰好位于List的子类上,并且作者想要将值作为List传递。 / p>

答案 5 :(得分:2)

怎么样?
private void doSomething(final List<T> list) {
    final ArrayList<T> arrayList;
    if (list instanceof ArrayList) {
        arrayList = (ArrayList<T>) list;
    } else {
        arrayList = new ArrayList<T>(list);
    }
            ...
    arrayList.trimToSize();
}

当然,我同意Chinmay Kanchi:对于一个私有方法,接受一个比必要更通用的类型是没有意义的。我的方法只有在修改给定列表没有问题时才可行。

答案 6 :(得分:1)

您的第一个方法会更改传递给方法的List,而另一个方法则不会。两种方法无法比较。

答案 7 :(得分:0)

由于它是一个私有方法,因此使用List接口的约定并不过分重要。没有公共API受到影响,因此请使用最方便的方法在类中使用。

例如,如果其他5个方法使用可能不同类型的List调用此方法,则使用第二个选项并将转换集中在1方法中(如果愿意,您甚至可以检查类型而不转换)。如果你的类只在内部处理ArrayList,并且你知道它在调用时将会是什么,那么将它声明为ArrayList并让你的生活变得轻松。