首页 > 解决方案 > 数组列表的三种声明方式有什么区别,为什么要先写接口,再写实现类?

问题描述

我是Java的初学者。我有两个基本问题。

  1. 当我们将数组列表的声明写为

    1. List l=new ArrayList<String>();
    2. List<String> l=new ArrayList<String>();
    3. List<String> l=new ArrayList<>();

    我看到所有上述陈述都没有给出任何错误。当我们选择一种方法来声明任何集合时,它会产生什么不同?

  2. 当我们将集合初始化为

    1. List<String>l = new ArrayList<String>();

    所以如果我们像下面这样声明

    1. ArrayList<String> l= new ArrayList<String>();

    1 和 2 有什么区别,为什么我们在使用集合时主要选择 2?

标签: java

解决方案


a) List l = new ArrayList<String>();与 相同List<Object> l = new ArrayList<String>();。这意味着该变量l是一个列表,可以存储任何Object,但不仅仅是一个字符串。此外,如果要将列表的值用作字符串,则需要转换它们。所以下面的代码会编译(这通常不是你想要的):

List l = new ArrayList<String>();
l.add("a string");//adding a String type is what is expected here
l.add(42);//adding an int is not realy expected here, but works
l.add(new Date());//also adding any other object is allowed

String s = (String) l.get(0);//s will be "a string"
String s2 = (String) l.get(1);//runtime error, since 42 can't be cast into a String

b) List<String> l=new ArrayList<String>();表示该变量l是一个字符串列表,并且只接受字符串值。以下代码会导致编译器错误:

List<String> l = new ArrayList<String>();
l.add("a string");//adding a String type is what is expected here
l.add(42);//compiler error
l.add(new Date());//compiler error

c) List<String> l=new ArrayList<>();基本相同List<String> l=new ArrayList<String>();。菱形运算符<>只是表示编译器应该清楚,这里使用的是哪种类型,所以程序员可以偷懒,让编译器完成工作。


p) List<String>l = new ArrayList<String>();告诉编译器, l 是List类型。因此,如果您想将 an 分配ArrayList给变量 l,这是允许的,并且如果您随后决定 aLinkedList更好,您仍然可以分配 aLinkedList并且它仍然可以工作,因为LinkedList两者ArrayList都实现了 interface List。因此,以下代码将起作用

List<String> l = new ArrayList<String>();
//later on you decide to change the type (maybe for a better performance or whatever)
l = new LinkedList<String>();
//use the List l like nothing has changed. You just don't need to care.

q) ArrayList<String> l= new ArrayList<String>();表示该变量l是 anArrayList并且永远不能是任何其他List实现(如 a LinkedList),因此您不能轻易更改实现。因此,以下代码将无法编译:

List<String> l = new ArrayList<String>();
//later on you decide to change the type (maybe for a better performance or whatever)
l = new LinkedList<String>();//compiler error; now you need to change many parts of your code if you still want to change the type of l to a LinkedList

因此通常p是更好的解决方案,因为您可以轻松更改代码。只有你需要调用不属于List接口的方法,比如它的trimToSize方法ArrayList可能需要使用q。但这是非常罕见的情况。


概括:

在几乎所有情况下,使用p比使用q更好。
同样在几乎所有情况下,使用bc比使用a更好。无论您使用b还是c并不重要。c稍微短一点。


推荐阅读