为什么数组不能分配给Iterable?

用Java5我们可以这样写:

Foo[] foos = ... for (Foo foo : foos) 

或者只是在for循环中使用Iterable。 这非常方便。

但是你不能像这样写一个迭代的通用方法:

 public void bar(Iterable<Foo> foos) { .. } 

并用一个数组调用它,因为它不是一个可迭代的:

 Foo[] foos = { .. }; bar(foos); // compile time error 

我想知道这个devise决定背后的原因。

数组可以实现接口( Cloneablejava.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中有类似的东西有任何进展,我会有兴趣知道在评论! 🙂