偶尔我会看到有人像这样创建一个arraylist,为什么?
List numbers = new ArrayList( );
而不是:
ArrayList<something> numbers = new ArrayList<something>();
答案 0 :(得分:7)
如果您询问使用界面而不是具体对象,那么这是一个很好的做法。想象一下,明天你将切换到LinkedList
。在第一种情况下,您不需要修复变量声明。
如果问题是关于非使用泛型,那就不好了。仿制药总是很好,因为它们可以提供类型安全性。
答案 1 :(得分:2)
有什么好处: 1.列表是许多实现的一般情况。
List trololo = new ListImpl();
隐藏用户的真实实现:
public list giveMeTheList(){ List trololo = new SomeCoolListImpl(); 回归控制; }
通过设计很好:用户不应该注意实现。他只是获得了实现的接口访问权限。实现应该已经具有所有必要的属性:快速添加,快速插入或不可修改,e.t.c。
有什么不好: 我已经读过所有原始类型将在未来的Java版本中受到限制,所以这样的代码更好地用这种方式编写:
List<?> trololo = new ListImpl<?>();
一般情况下,通配符具有相同的含义:您不确定您的收集是异质的还是同质的?
答案 2 :(得分:1)
有一天你可以这样做:
List<something> numbers = new LinkedList<something>();
而不更改调用numbers
的客户端代码。
答案 3 :(得分:1)
声明界面而不是实现确实是相当好的和普遍的做法,但它不是始终最好的方式。除了满足以下所有条件外,每次都使用它:
ArrayList.trimToSize()
当然,你可以使用强制转换,但是使用界面毫无意义。
答案 4 :(得分:1)
第一行是旧式 Java,我们必须在Java 1.5引入泛型之前完成。但许多优秀的软件工程师仍被迫使用Java 1.4(或更低版本),因为他们的公司担心风险和努力升级应用程序...
好的,那是关闭记录的。许多遗留代码都是使用java 1.4或更低版本生成的,并且尚未重构。第二行包括泛型(因此它显然是1.5+),变量被声明为ArrayList
。实际上没有大问题。当然,总是更好地对接口进行编码,因此对于我(和其他人)的意见,除非确实需要特殊的ArrayList
方法,否则不要将变量声明为ArrayList
。
答案 5 :(得分:1)
大多数情况下,当您不关心实现时,最好编程接口。所以,像:
List<something> numbers = new ArrayList<something>();
优先于:
ArrayList<something> numbers = new ArrayList<something>();
原因是您可以稍后调整您的程序,以提高性能。
但是,你必须要小心,不要只选择最通用的界面。例如,如果您想要排序集,而不是设置,则应编程为 SortedSet ,如下所示:
SortedSet<something> s = new TreeSet<something>();
如果你只是公然使用这样的界面:
Set<something> s = new TreeSet<something>();
有人可以将实施修改为 HashSet ,您的程序将被破坏。
最后,当您定义公共API时,此接口程序甚至会更有用。
答案 6 :(得分:0)
两个不同之处在于,第一行中的numbers
属于List
,而非ArrayList
。这是可能的,因为ArrayList
是List
的后代;也就是说,它包含List
所拥有的所有内容,因此可以填写List
个对象。 (这不相反。)
输入第二行的ArrayList
。这意味着第二个numbers
列表只能包含类型something
对象。