本着最佳实践的精神:总是返回一个____,从来没有____,我在即将从JDK1.4.2迁移到JDK5等等时遇到了类似的问题.(是的,我知道,JDK1.4.2是EOL! ;-)).
对于返回集合的函数(不是简单的属性集合),我总是更喜欢(在JDK1.4.2中)返回一个Array而不是一个通用的List,因为:
它强制执行返回类型(MyObject[]
而不是对象列表,更多类型安全的静态 - 如'编译' - 级别)
它为返回的集合建议了一个"只读"字符(将一个元素添加到集合中会更复杂,即使这不像c#中的'只读'关键字那样严格).这与说"不可变"不同,因为数组中的引用仍然可以修改...
当然,我总是创建这个返回的数组(我没有公开任何'内部'数组)
现在,在JDK5及更多版本中,List
如果我愿意,我可以使用它.
选择返回MyObject[]
而不是List或Collection
在java5中编码时有什么好理由?
如果Collection
使用奖金,可以:
对返回的集合强制执行只读属性?(没有add()
或remove()
可能)
对返回的集合强制执行不可变的方面?(甚至不能修改该集合的引用)
PS:JavaGenericFAQ没有那个.
首选集合(或列表,或适当设置)到数组.使用泛型,您可以获得缺少Java 5之前的类型检查.此外,通过仅公开接口,您可以稍后更改实现(例如,为LinkedList切换ArrayList).
数组和泛型不能很好地混合.因此,如果您想利用泛型,通常应该避免使用数组.
即:你不能一般地创建一个数组.例如,如果T是泛型类型,则"new T [0]"不会编译.您必须执行类似"(T [])new Object [0]"的操作,它会生成未经检查的强制转换警告.出于同样的原因,您不能在没有警告的情况下使用带有varargs的泛型类型.
使用Collections.unmodifiableCollection(和类似方法),您将获得只读约束(使用数组无法实现 - 您必须返回数组的克隆).
你不能强制成员的不变性,但是你也不能用数组做到这一点.
实际上,数组仍然比集合/列表有一个优势.由于Java通过类型擦除实现泛型的方式,您不能有两种方法将Collections作为参数,但只有Collection的泛型类型不同.
例如:
public void doSomething(Collectionstrs) { ... } public void doSomething(Collection ints) { ... }
上述两种方法无法编译,因为javac编译器使用类型擦除,因此无法将类型信息传递给JVM.JVM只会看到两个以Collection作为参数的方法.
在上面的例子中,最好的解决方法是使方法将数组作为参数,并在将参数传递给它们时使用Collection/List的toArray()方法.如果你仍想在上面的方法中使用Collection/List,只需使用java.util.Arrays.asList()方法来获取你的List.
例如:
public void doSomething(String[] strs) { ListstrList = Arrays.asList(strs); ... } public void doSomething(Integer[] ints) { List intList = Arrays.asList(ints); ... } public static void main(String[] args) { List strs = new ArrayList (); List ints = new ArrayList (); obj.doSomething(strs.toArray()); obj.doSomething(ints.toArray()); }