声明List<Integer>和ArrayList<Integer>有什么区别?

10
List<Integer> mylist = new ArrayList<Integer>();

ArrayList<Integer> mylist2 = new ArrayList<Integer>();

我想知道在Java集合API中,上述两者的实际区别是什么。我对Java集合API还不熟悉。我知道List是一个接口,而ArrayList类则实现了它。


第二种形式更好。 - irreputable
2
@irreputable:我认为你打错了。 - Keppil
5
“@irreputable:那是不对的。虽然有些情况下声明实际类型更好,但通常最佳做法是声明接口类型。” - Keppil
2
@irreputable:我不同意。具体来说,使用你需要的最“广泛”类型。如果你有一个只使用hashCode()toString()的方法-使用Object-它将使您以后更容易地重构代码。这在谈论实例和类变量时尤其正确。 - amit
@amit,特别是对于实例/类变量来说,它们的类型需要比局部变量更明确。 - irreputable
显示剩余2条评论
7个回答

8
List<Integer>版本是接口类型,它只允许您执行由接口声明的方法,而ArrayList<Interger>类型的变量允许您执行在ArrayList<Interger>及其超类中声明的任何操作(当然包括List)。
但是,尽管选择第一个似乎“无用”,但实际上它允许您更灵活地改变设计,如果您以后决定要使用LinkedList<Interger>(例如),而不是ArrayList<Interger>作为动态类型,则可以更轻松地进行更改。
补充:
当然,这并不意味着您需要自动选择List<Integer>版本。如果您确实需要使用ArrayList的确切类型,则应该选择它。一个很好的经验法则是从接口版本开始,并仅在发现您难以使用ArrayList类型(或者发现自己将其强制转换为ArrayList时)才将其更改为ArrayList<Integer>

2
在你的第一句话中,由于你将mylist表示为List<Integer>,而它仍然是ArrayList<Integer>因此你只能使用List接口中提供的方法。如果你使用跨类/方法的功能,这是更好的陈述方式。
此外,任何接受List<Integer>的方法都可以接受List的任何实现类,例如LinkedList<Integer>或你自己的实现类。
你的第二个陈述仅创建并引用ArrayList<Integer>对象。有些人喜欢在方法中仅在本地使用mylist

谢谢,伙计,你的解释让我非常清楚了。所以,这意味着对于mylist,我可以使用List接口的所有方法,但是对于mylist,我只能使用ArrayList类的方法,对吗? - user1876712

2

始终按接口编码。

(汽车比喻警报)

你走进赫兹租车公司。 你说,我想要一个IVehicle。 他们说,“好的,什么类型IVehicle?” 你不在意。 所以他们给了你一辆DumpTruck。 但你不想要一辆自卸车,你想要紧凑型的东西。 你想要一个扩展了IVehicleICompact。 所以他们给了你一辆摩托车。 “不!”你大声喊道,“我想要一辆ICar!” “什么样的ICar?”他们问道。 “我不在乎!”你大声喊道。 所以他们给了你一辆FordCar,然后你就过上了幸福快乐的生活。

这下清楚了吗?


1

首先是接口编程。

在整个代码中使用 List 引用,您可以将具体实现更新为其他内容,例如 LinkedList,而不会破坏客户端代码。


1

你可以把它看作是多态性。

List<Integer> mylist 声明它为 List,但它不一定是 ArrayList - JVM 只知道它实现了 List 接口。

ArrayList<Integer> mylist2 声明它为 ArrayList,因此 JVM 知道它不仅是 List,而且特别是 ArrayList。


0
我知道List是一个接口,ArrayList类实现了它。
这正是它们的区别 :)
当你在代码中使用两个变量(mylist)和(mylist2),你只能在mylist2上访问任何ArrayList定义的不属于基本List接口的方法。

0

对于myList,您只能调用List接口的方法。

例如,您不能在myList上调用ensureCapacity方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接