Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #34746

Re: Two surprises in for (:)

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>

Show all headers | View raw


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


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