![](/img/trans.png)
[英]Why is java.util.Set not Assignable From java.lang.Iterable?
[英]Why is an array not assignable to Iterable?
使用 Java5 我們可以這樣寫:
Foo[] foos = ...
for (Foo foo : foos)
或者只是在 for 循環中使用 Iterable。 這非常方便。
但是,您不能像這樣為 iterable 編寫通用方法:
public void bar(Iterable<Foo> foos) { .. }
並使用數組調用它,因為它不是 Iterable:
Foo[] foos = { .. };
bar(foos); // compile time error
我想知道這個設計決定背后的原因。
數組可以實現接口( Cloneable
和java.io.Serializable
)。 那么為什么不Iterable
呢? 我猜Iterable
強制添加iterator
方法,而數組不實現方法。 char[]
甚至不覆蓋toString
。 無論如何,引用數組應該被認為不太理想——使用List
s。 正如 dfa 評論的那樣, Arrays.asList
將明確地為您進行轉換。
(話雖如此,您可以在數組上調用clone
。)
該數組是一個對象,但它的項目可能不是。 該數組可能包含像 int 這樣的原始類型,這是 Iterable 無法處理的。 至少我是這么認為的。
數組應該支持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>
沒有繼承IReadOnlyList<T>
:
IList<int> c = new List<int> { 1, 2, 3, 4 };
IReadOnlyList<int> d = c; // error
這樣的更改可能存在向后兼容性問題。
如果在較新版本的 Java 中類似的事情有任何進展,我很想在評論中知道::)
不幸的是,數組不夠“ class
”。 他們不實現Iterable
接口。
雖然數組現在是實現 Clonable 和 Serializable 的對象,但我認為數組不是正常意義上的對象,並且不實現接口。
您可以在 for-each 循環中使用它們的原因是因為 Sun 為數組添加了一些語法糖(這是一種特殊情況)。
由於數組從 Java 1 開始就是“幾乎是對象”,因此要使它們成為 Java 中的真正對象,變化太大了。
編譯器實際上將數組上的for each
轉換為帶有計數器變量的簡單for
循環。
編譯如下
public void doArrayForEach() {
int[] ints = new int[5];
for(int i : ints) {
System.out.println(i);
}
}
然后反編譯.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);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.