List<String> list = new ArrayList<>();
或 Set<String> set = new HashSet<>();
。对我来说,使用接口作为变量类型以提供实现的灵活性是很有道理的。上述示例仍然定义了必须使用哪种Collection
,或者允许哪些操作以及在某些情况下应该如何行为(由于文档)。现在考虑这种情况:实际上只需要使用
Collection
(甚至是Iterable
)接口的功能来使用类中的字段,并且Collection
的类型并不重要,或者我不想过度指定它。因此,我选择例如HashSet
作为实现,并将字段声明为Collection<String> collection = new HashSet<>();
。在这种情况下,该字段是否应该是
Set
类型?如果是,这种声明方式是否是不良实践?如果是,为什么?或者,尽可能少地指定实际类型(仍然提供所有所需方法)是好的实践。我之所以问这个问题,是因为我几乎从未见过这样的声明,最近我越来越多地发现自己只需要指定Collection
接口的功能。// Only need Collection features, but decided to use a LinkedList
private final Collection<Listener> registeredListeners = new LinkedList<>();
public void init() {
ExampleListener listener = new ExampleListener();
registerListenerSomewhere(listener);
registeredListeners.add(listener);
listener = new ExampleListener();
registerListenerSomewhere(listener);
registeredListeners.add(listener);
}
public void reset() {
for (Listener listener : registeredListeners) {
unregisterListenerSomewhere(listener);
}
registeredListeners.clear();
}
init()
方法两次时会发生什么?只需考虑这里Set
与List
的选择如何干扰registerListenerSomewhere
方法的行为:它将在那里存储在Set
还是List
中?如果它在那里存储在List
中,但在您的类中存储在Set
中,则调用reset
将仅删除一个侦听器实例,而不是所有侦听器实例。这很困难... - Marco13