java5では、次のように記述できます。
Foo[] foos = ...
for (Foo foo : foos)
または、forループで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
を呼び出すことができます。)
配列はオブジェクトですが、そのアイテムはそうでない場合があります。配列は、Iterableが対応できないintのようなプリミティブ型を保持する場合があります。少なくともそれは私が考えるものです。
配列はIterable
をサポートする必要がありますが、.NET配列が位置による読み取り専用ランダムアクセスを許可するインターフェイスをサポートしないのと同じ理由で、サポートしません(そのようなインターフェイスは標準として定義されていません)。基本的に、フレームワークにはしばしば迷惑な小さなギャップがありますが、これを修正する時間はありません。最適な方法で修正できるかどうかは関係ありませんが、多くの場合、できません。
PDATE:公平を期すため、位置によるランダムアクセスをサポートするインターフェイスをサポートしていない.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
- enough」ではありません。 Iterable
インターフェイスを実装していません。
配列はClonableとSerializableを実装するオブジェクトになりましたが、配列は通常の意味ではオブジェクトではありませんであり、インターフェイスを実装していません。
For-eachループでそれらを使用できる理由は、Sunが配列のシンタックスシュガーを追加したためです(特殊なケースです)。
配列はJava 1で 'ほとんどのオブジェクト'として始まったため、それらを変更するのはあまりにも劇的すぎるrealJavaのオブジェクト。