为什么在Java中使用接口名称声明变量?

Zil*_*ilk 17 java variables interface declaration

这是一个真正的初学者问题(我还在学习Java基础知识).

我可以(有点)理解为什么方法会返回List <String>而不是ArrayList <String>,或者为什么它们会接受List参数而不是ArrayList.如果它对方法没有影响(即,如果不需要ArrayList中的特殊方法),这将使该方法更灵活,更容易用于调用者.其他集合类型也是如此,例如Set或Map.

我不明白的是:通常的做法是创建这样的局部变量:

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

虽然这种形式不太常见:

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

这有什么好处?

我只能看到一个小缺点:必须添加java.util.List的单独"import"行.从技术上讲,可以使用"import java.util.*",但我也不经常看到,可能是因为某些IDE自动添加了"import"行.

Meh*_*ari 21

当你读

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

你明白你所关心的只是一个List<String>,你不太重视实际的实现.此外,您将自己限制为声明的成员List<String>而不是特定的实现.你不关心你的数据是存储在一个线性数组还是一些奇特的数据结构中,只要它看起来像一个List<String>.

另一方面,阅读第二行可以让您了解代码关注的是变量ArrayList<String>.通过写这个,你隐含地(对未来的读者)说你不应该盲目地改变实际的对象类型,因为其余的代码依赖于它真的是一个事实ArrayList<String>.

  • 这是抽象的.一个实现与另一个实现的效率取决于_uses_变量的代码:我看不出除了两者之间的紧密耦合之外我什么都不想要. (6认同)
  • 希望松散耦合到局部变量的一个原因是当局部暴露时.换句话说,返回List通常比使用ArrayList更好.将变量声明为List可以鼓励这样做. (3认同)

Mik*_*ell 7

使用该界面可以快速更改List/Map/Set/etc的底层实现.

这不是关于保存击键,而是关于快速改变实施.理想情况下,您不应该公开实现的基础特定方法,只需使用所需的接口.