为什么应该首选Java类的接口?

为什么应该首选Java类的接口?,java,collections,interface,Java,Collections,Interface,将报告以下违规行为: ArrayList<Object> list = new ArrayList<Object>(); 冲突是避免使用诸如“ArrayList”之类的实现类型;改用界面 以下行将更正违规行为: List<Object> list = new ArrayList<Object>(); 为什么要将后者与列表一起使用而不是使用ArrayList?这是首选,因为您将代码与列表的实现解耦。使用接口可以轻松地将实现(在本例中为ArrayL

将报告以下违规行为:

ArrayList<Object> list = new ArrayList<Object>();
冲突是避免使用诸如“ArrayList”之类的实现类型;改用界面

以下行将更正违规行为:

List<Object> list = new ArrayList<Object>();

为什么要将后者与列表一起使用而不是使用ArrayList?

这是首选,因为您将代码与列表的实现解耦。使用接口可以轻松地将实现(在本例中为ArrayList)更改为另一个列表实现,而无需更改任何其他代码,只要它只使用列表中定义的方法。

在具体类型上使用接口是实现良好封装和代码松耦合的关键

在编写自己的API时,遵循这种做法甚至是一个好主意。如果您这样做了,您将在稍后发现,使用模拟技术将单元测试添加到代码中,并在将来需要时更改底层实现更容易

这是一个关于这个问题的报告


希望有帮助

ArrayList和LinkedList是列表的两种实现,列表是项的有序集合。从逻辑上讲,使用ArrayList或LinkedList并不重要,因此不应将类型限制为该类型


这与例如,Collection和List形成了对比,后者是不同的事物,List意味着排序,Collection则不是。

一般来说,对于您的代码行来说,使用接口是没有意义的。但是,如果我们谈论的是API,那么有一个很好的理由。我上小班

class Counter {
    static int sizeOf(List<?> items) {
        return items.size();
    }
}

在这种情况下,需要使用接口。因为我想计算每个可能实现的大小,包括我自己的自定义。类MyList扩展了AbstractList

类/接口的属性应该通过接口公开,因为它为类提供了可使用的行为契约,而与实现无关

然而

在局部变量声明中,这样做没有什么意义:

public void someMethod() {
List theList = new ArrayList();
//do stuff with the list
}

如果是局部变量,只需使用类型。它仍然可以隐式地向上转换到相应的接口,并且您的方法应该希望接受其参数的接口类型,但是对于局部变量,使用实现类型作为容器是完全有意义的,以防您确实需要特定于实现的功能。

一般来说,我同意将接口与实现分离是一件好事,这将使您的代码更易于维护

但是,你必须考虑到一些例外情况。通过接口访问对象会增加一个额外的间接层,这会降低代码的速度

出于兴趣,我做了一个实验,生成了对一个100万长度的ArrayList的100亿次顺序访问。在我的2.4Ghz MacBook上,通过列表接口访问ArrayList平均需要2.10秒,而将其声明为ArrayList类型平均需要1.67秒


如果你使用大列表,深入内部循环或频繁调用函数,那么这是要考虑的事情。

即使对于局部变量,使用在具体类上的接口也有帮助。您可能会最终调用接口之外的方法,然后在必要时很难更改列表的实现。 此外,最好在声明中使用最不特定的类或接口。如果元素顺序无关紧要,请使用集合而不是列表。这使您的代码具有最大的灵活性

为什么要使用带列表的后者而不是ArrayList

这是一个很好的实践:从程序到接口,而不是实现

通过将ArrayList替换为List,您可以在将来根据您的业务用例更改List实现,如下所示

List<Object> list = new  LinkedList<Object>(); 
/* Doubly-linked list implementation of the List and Deque interfaces. 
 Implements all optional list operations, and permits all elements (including null).*/

其他一些特定于列表的实现

列表接口定义了合同,列表的具体实现可以更改。通过这种方式,接口和实现是松散耦合的

相关问题:


接口向最终用户公开。一个类可以实现多个接口。公开特定界面的用户可以访问特定界面中定义的特定行为

一个接口也有多个实现。基于场景系统将与不同场景的界面实现


如果您需要更多解释,请告诉我。

在调试器视图中,接口通常比具体类具有更好的表示。

@Owen:+5深刻的re:性能差异。。。这是一个非常出乎意料的答案,但是它表明开销可能非常小:哇!100亿次访问0.5秒,即1次接口访问比类访问慢半纳秒!这当然是一个永远不要使用接口的原因。如果您对ArrayList这样的实现进行编码,那么您完全有可能使用实现e的方法
即使你可以用接口方法做同样的事情。这会将您的代码绑定到实现,使以后在实现之间切换变得更加困难。另请参阅,关于使用集合而不是列表,我们将在抽象中更进一步…?关于使用集合而不是列表,以便可以使用列表或集合,例如
List<Object> list = new  CopyOnWriteArrayList<Object>(); 
/* A thread-safe variant of ArrayList in which all mutative operations
 (add, set, and so on) are implemented by making a fresh copy of the underlying array.*/
List<Object> list = new  Stack<Object>(); 

/* The Stack class represents a last-in-first-out (LIFO) stack of objects.*/