Java 为什么数组不能分配给 Iterable?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1160081/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why is an array not assignable to Iterable?
提问by dfa
with Java5 we can write:
使用 Java5 我们可以这样写:
Foo[] foos = ...
for (Foo foo : foos)
or just using an Iterable in the for loop. This is very handy.
或者只是在 for 循环中使用 Iterable 。这非常方便。
However you can't write a generic method for iterable like this:
但是,您不能像这样为可迭代编写通用方法:
public void bar(Iterable<Foo> foos) { .. }
and calling it with an array since it is not an Iterable:
并使用数组调用它,因为它不是可迭代的:
Foo[] foos = { .. };
bar(foos); // compile time error
I'm wondering about the reasons behind this design decision.
我想知道这个设计决定背后的原因。
采纳答案by Tom Hawtin - tackline
Arrays can implement interfaces (Cloneable
and java.io.Serializable
). So why not Iterable
? I guess Iterable
forces adding an iterator
method, and arrays don't implement methods. char[]
doesn't even override toString
. Anyway, arrays of references should be considered less than ideal - use List
s. As dfa comments, Arrays.asList
will do the conversion for you, explicitly.
数组可以实现接口(Cloneable
和java.io.Serializable
)。那么为什么不Iterable
呢?我想Iterable
强制添加一个iterator
方法,而数组不实现方法。char[]
甚至不覆盖toString
. 无论如何,引用数组应该被认为不太理想 - 使用List
s。正如 dfa 评论的那样,Arrays.asList
将明确地为您进行转换。
(Having said that, you can call clone
on arrays.)
(话虽如此,您可以调用clone
数组。)
回答by jjnguy
Unfortunately, arrays aren't 'class
-enough'. They don't implement the Iterable
interface.
不幸的是,数组不是“class
足够的”。他们不实现Iterable
接口。
While arrays are now objects that implement Clonable and Serializable, I believe an array isn't an object in the normal sense, and doesn't implement the interface.
虽然数组现在是实现了 Clonable 和 Serializable 的对象,但我相信数组不是正常意义上的对象,也没有实现接口。
The reason you can use them in for-each loops is because Sun added in some syntatic sugar for arrays (it's a special case).
您可以在 for-each 循环中使用它们的原因是 Sun 为数组添加了一些语法糖(这是一种特殊情况)。
Since arrays started out as 'almost objects' with Java 1, it would be far too drastic of a change to make them realobjects in Java.
由于数组在 Java 1 中是作为“几乎对象”开始的,因此在 Java中使它们成为真正的对象将是非常剧烈的变化。
回答by Daniel Earwicker
Arrays ought to support Iterable
, they just don't, for the same reason that .NET arrays don't support an interface that allows readonly random access by position (there is no such interface defined as standard). Basically, frameworks often have annoying little gaps in them, which it's not worth anyone's time to fix. It wouldn't matter if we could fix them ourselves in some optimal way, but often we can't.
数组应该支持Iterable
,他们只是不支持,原因与 .NET 数组不支持允许按位置进行只读随机访问的接口相同(没有这样的接口定义为标准)。基本上,框架中通常有令人讨厌的小漏洞,不值得任何人花时间来修复。如果我们能以某种最佳方式自己修复它们并不重要,但通常我们不能。
UPDATE:To be even-handed, I mentioned .NET arrays not supporting an interface that supports random access by position (see also my comment). But in .NET 4.5 that exact interface has been defined and is supported by arrays and the List<T>
class:
更新:为了公平起见,我提到 .NET 数组不支持支持按位置随机访问的接口(另请参阅我的评论)。但是在 .NET 4.5 中,已经定义了确切的接口,并由数组和List<T>
类支持:
IReadOnlyList<int> a = new[] {1, 2, 3, 4};
IReadOnlyList<int> b = new List<int> { 1, 2, 3, 4 };
All is still not quite perfect because the mutable list interface IList<T>
doesn't inherit IReadOnlyList<T>
:
All 仍然不是很完美,因为可变列表接口IList<T>
没有继承IReadOnlyList<T>
:
IList<int> c = new List<int> { 1, 2, 3, 4 };
IReadOnlyList<int> d = c; // error
Maybe there is a possible backward compatibility gotcha with such a change.
也许这种更改可能存在向后兼容性问题。
If there's any progress on similar things in newer versions of Java, I'd be interested to know in the comments! :)
如果在较新版本的 Java 中在类似的事情上有任何进展,我很想在评论中知道!:)
回答by Gareth Adamson
The array is an Object, but its items might not be. The array might hold a primitive type like int, which Iterable can't cope with. At least that's what I reckon.
该数组是一个对象,但它的项目可能不是。该数组可能包含像 int 这样的原始类型,这是 Iterable 无法处理的。至少我是这么认为的。
回答by das Keks
The compiler actually translates the for each
on an array into a simple for
loop with a counter variable.
编译器实际上将for each
数组上的 转换为for
带有计数器变量的简单循环。
Compiling the following
编译如下
public void doArrayForEach() {
int[] ints = new int[5];
for(int i : ints) {
System.out.println(i);
}
}
and then decompiling the .class file yields
然后反编译 .class 文件产生
public void doArrayForEach() {
int[] ints = new int[5];
int[] var2 = ints;
int var3 = ints.length;
for(int var4 = 0; var4 < var3; ++var4) {
int i = var2[var4];
System.out.println(i);
}
}