Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #34746
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Newsgroups | comp.lang.java.programmer |
| Subject | Re: Two surprises in for (:) |
| Date | 2016-07-01 15:07 -0400 |
| Organization | A noiseless patient Spider |
| Message-ID | <nl6f14$ukj$1@dont-email.me> (permalink) |
| References | <nl6apt$gg5$1@dont-email.me> |
On 7/1/2016 1:55 PM, Mike Amling wrote:
> I was surprised that the javac compiler accepted the following:
>
> String[] foo={"a", "b"};
> for (final String who : foo) {
> }
>
> because it seems strange to have a for loop's variable work when final.
Well, the "for loop's variable" is not a particularly rigorous
description. Examples:
for (int i=0,j=10; i < j; ++i,--j) ...
for (; !theList.isEmpty(); theList.remove(0)) ...
Neither of these has a unique obvious "loop variable."
> After all,
>
> for (final int i=0; i<7; ++i) {
> }
>
> gets an error.
Yes, and I think that's unfortunate. Sometimes I want to use
`i' in a lambda expression (or in a nested class), and I must write
for (int i = 0; i < 7; ++i) {
final int iFinal = i;
// use iFinal in the lambda
}
> But for (final String who : foo) is more like an abbreviation of
>
> for (final Iterator<String> iter=foo.iterator(); iter.hasNext(); ) {
> final String who=iter.next();
> }
>
> wherein it's not strange that who can be final.
Not really "like" at all, because (as you go on to observe)
the latter won't compile ...
> My second surprise was that the compiler rejects
>
> String[] foo={"a", "b"};
> for (final Iterator<String> iter=foo.iterator(); iter.hasNext(); ) {
> final String who=iter.next();
> }
>
> apparently because arrays, unlike everything else accepted after the :
> in a for(:), do not actually implement the Iterable interface.
No, they don't. Observe that an array of primitives would be
unable to implement Iterable anyhow, because an Iterator's next()
must deliver an object reference. (The sharp distinction between
primitives and references is, I think, a shortcoming of Java -- but
it's there nonetheless, and we have to live with it.) For an array,
the code looks pretty much like
for (Type thing : array) ...
// Roughly equivalent to
Type[] $array = array;
for (int $idx = 0; $idx < $array.length; ++$idx) {
thing = $array[$idx];
...
(Note that the loop uses the `$array' temporary variable instead of
`array' itself; if `array' gets changed the loop continues its march
across the original array, not its replacement.)
The relevant bit of the JLS is at
http://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.14.2
--
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM
Back to comp.lang.java.programmer | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
Two surprises in for (:) Mike Amling <mamling@chaff.us> - 2016-07-01 12:55 -0500
Re: Two surprises in for (:) Eric Sosman <esosman@comcast-dot-net.invalid> - 2016-07-01 15:07 -0400
Re: Two surprises in for (:) Daniel Pitts <usenet@coloraura.com> - 2016-07-01 15:08 -0700
csiph-web