views:

943

answers:

4

with Java5 we can write:

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

or just using an Iterable in the for loop. This is very handy.

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.

+7  A: 

Unfortunately, arrays aren't 'class-enough'. They don't implement the Iterable interface.

Since an array isn't an object in the normal sense, it can't implement the interface.

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).

Since arrays started out as 'almost objects' with Java 1, it would be far too drastic of a change to make them real objects in Java.

jjnguy
well, I'm wondering exactly why they don't implement the Iterable interface!
dfa
Since an array isn't an object in the normal sense, it can't implement the interface.
jjnguy
@dfa I'm afraid only Sun could really answer that
matt b
they dont implement the iterable interface because they are not standard classes and cannot implement an interface
Spencer Stejskal
Still, there's sugar for the for-each loop, so why can't there be sugar for Iterable?
Michael Myers
You would think that they could make an array act more like an iterable.
jjnguy
@mmyers: The sugar used in for-each is *compile-time* sugar. That's a lot easier to do than *VM* sugar. Having said which, .NET arrays are significantly better in this area...
Jon Skeet
Arrays *can* implement interfaces. They implement `Cloneable` and `Serializable` interfaces.
notnoop
really ?
jjnguy
java arrays are objects in all senses. Please remove that bit of misinformation. They just don't implement Iterable.
ykaganovich
matt b: Most of the people who works on the 1.5 languages features no longer work for Sun.
Tom Hawtin - tackline
An array is an Object. It support *useful* :P methods like wait(), wait(n), wait(n,m), notify(), notifyAll(), finalize(), a pointless implementation of toString() The only useful method is getClass().
Peter Lawrey
+2  A: 

As msaeed comments, 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 Lists. As dfa comments, Arrays.asList will do the conversion for you, explicitly.

(Having said that, you can call clone on arrays.)

Tom Hawtin - tackline
@Joachim Sauer should read "doesn't".
Tom Hawtin - tackline
+3  A: 

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.

Daniel Earwicker
+5  A: 

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.

Gareth Adamson