为什么数组不能分配给Iterable?
用Java5我们可以这样写:
Foo[] foos = ... for (Foo foo : foos)
或者只是在for循环中使用Iterable。 这非常方便。
但是你不能像这样写一个迭代的通用方法:
public void bar(Iterable<Foo> foos) { .. }
并用一个数组调用它,因为它不是一个可迭代的:
Foo[] foos = { .. }; bar(foos); // compile time error
我想知道这个devise决定背后的原因。
数组可以实现接口( Cloneable
和java.io.Serializable
)。 那么为什么不可以Iterable
呢? 我猜Iterable
力量添加一个iterator
方法,并且数组不执行方法。 char[]
甚至不会覆盖toString
。 无论如何,引用数组应该被认为不太理想 – 使用List
。 作为dfa注释, Arrays.asList
将明确地为您做转换。
(话说回来,你可以在数组上调用clone
。)
该数组是一个对象,但它的项目可能不是。 该数组可能拥有一个像int这样的基本types,Iterable无法应对。 至less这就是我认为的。
不幸的是,数组不是' class
enough'。 他们不实现Iterable
接口。
虽然数组现在是实现Clonable和Serializable的对象,但我相信一个数组不是一个普通意义上的对象 ,也不会实现这个接口。
你可以在每个循环中使用它们的原因是因为Sun在数组中添加了一些syntally糖(这是一个特例)。
由于数组在Java 1中开始是“几乎是对象”,所以在Java中使它们成为真实对象将是一个非常激烈的改变。
数组应该支持Iterable
,他们不会,因为.NET数组不支持只允许按位访问的随机访问接口(没有这样的接口定义为标准)。 基本上,框架往往有恼人的小差距,这是不值得任何人的时间去解决。 如果我们能够以一种最佳的方式来解决这些问题并不重要,但我们通常不能。
更新:为了公平,我提到.NET数组不支持按位置随机访问的接口(另见我的评论)。 但在.NET 4.5中,确切的接口已经被定义,并且被数组和List<T>
类所支持:
IReadOnlyList<int> a = new[] {1, 2, 3, 4}; IReadOnlyList<int> b = new List<int> { 1, 2, 3, 4 };
所有仍然不完美,因为可变列表接口IList<T>
不inheritanceIReadOnlyList<T>
:
IList<int> c = new List<int> { 1, 2, 3, 4 }; IReadOnlyList<int> d = c; // error
也许有这样一个变化可能的后向兼容性问题。
如果在更新版本的Java中有类似的东西有任何进展,我会有兴趣知道在评论! 🙂