为什么要首选Java类的接口?

jna*_*eta 71 java collections interface

PMD将报告违规行为:

ArrayList<Object> list = new ArrayList<Object>();
Run Code Online (Sandbox Code Playgroud)

违规是"避免使用像'ArrayList'这样的实现类型;而是使用接口".

以下行将更正违规行为:

List<Object> list = new ArrayList<Object>();
Run Code Online (Sandbox Code Playgroud)

为什么要使用后者List而不是ArrayList

kol*_*rie 79

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

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

这是一篇关于这个主题的好文章.

希望能帮助到你!

  • 那么使用“Collection”而不是“List”怎么样,这样我们就可以在抽象上更进一步......? (2认同)

Ada*_*amC 29

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


Owe*_*wen 12

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

但是,您必须考虑例外情况.通过接口访问对象会增加一个额外的间接层,使您的代码变慢.

为了兴趣,我进行了一项实验,该实验对100万长度的ArrayList产生了100亿次顺序访问.在我的2.4Ghz MacBook上,通过List接口访问ArrayList的平均时间为2.10秒,当声明类型为ArrayList时,它平均需要1.67秒.

如果您正在使用大型列表,深入内部循环或经常调用函数,那么这是需要考虑的事情.

  • 哇!100亿次访问0.5秒,即1个接口访问比一个类访问慢半纳秒!这当然是永远不要使用接口的原因。 (3认同)
  • 然而,这个答案显示开销可能非常小:http://stackoverflow.com/questions/890687/overhead-of-implementing-an-interface/891096#891096 (2认同)

SCd*_*CdF 6

ArrayList和LinkedList是List的两个实现,它是一个有序的项集合.逻辑方面,如果您使用ArrayList或LinkedList并不重要,因此您不应该将类型约束为该类型.

这与Collection和List形成鲜明对比,它们是不同的东西(List暗示排序,Collection不是).