Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #34745 > unrolled thread
| Started by | Mike Amling <mamling@chaff.us> |
|---|---|
| First post | 2016-07-01 12:55 -0500 |
| Last post | 2016-07-01 15:08 -0700 |
| Articles | 3 — 3 participants |
Back to article view | Back to comp.lang.java.programmer
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
| From | Mike Amling <mamling@chaff.us> |
|---|---|
| Date | 2016-07-01 12:55 -0500 |
| Subject | Two surprises in for (:) |
| Message-ID | <nl6apt$gg5$1@dont-email.me> |
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.
After all,
for (final int i=0; i<7; ++i) {
}
gets an error.
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.
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.
--Mike Amling
SSBzdXBwb3NlIGEgbG90IG9mIHlvdSBhcmUgbm90IHN1cnBpc2VkLg==
[toc] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2016-07-01 15:07 -0400 |
| Message-ID | <nl6f14$ukj$1@dont-email.me> |
| In reply to | #34745 |
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
[toc] | [prev] | [next] | [standalone]
| From | Daniel Pitts <usenet@coloraura.com> |
|---|---|
| Date | 2016-07-01 15:08 -0700 |
| Message-ID | <nl6pks$68q$1@dont-email.me> |
| In reply to | #34746 |
On 7/1/16 12:07 PM, Eric Sosman wrote:
> 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
> }
Or something along the lines: IntStream.range(0, 7).forEach(i ->
doSomethingWithLambda(() -> doSomethingWith(i));
> [snip]
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.java.programmer
csiph-web