PMD 会报告违规行为:

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

违规是<!>;避免使用像'ArrayList'这样的实现类型;使用界面改为<!> quot;。

以下行将更正违规行为:

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

为什么后者用List代替ArrayList

有帮助吗?

解决方案

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

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

这是关于的好文章主题。

希望它有所帮助!

其他提示

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

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

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

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

如果您正在处理大型列表,内部循环内部或经常调用的函数,则需要考虑这一点。

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

这与“收集”和“列表”形成鲜明对比,后者是不同的东西(列表意味着排序,收集不会)。

  

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

这是一个很好的做法:程序接口而不是实现

ArrayList替换为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).*/

OR

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.*/

OR

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

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

OR

其他一些<=>具体实施。

<=>接口定义合同,<=>的具体实现可以更改。通过这种方式,接口和实现松散耦合。

相关的SE问题:

对于<!>“程序意味着什么到界面<!> quot;?

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

您的类/接口的属性应该通过接口公开,因为它为您的类提供了一个行为契约,无论其实现如何。

...然而

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

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

如果是局部变量,只需使用该类型即可。它仍然可以隐式地向上转换为其适当的接口,并且您的方法应该有希望接受其参数的接口类型,但对于局部变量,将实现类型用作容器是完全合理的,以防万一您确实需要实现 - 具体功能。

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

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

在这种情况下,需要使用接口。因为我想计算每个可能的实现的大小,包括我自己的自定义。 class MyList extends AbstractList<String>...

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top