Stranger compiler error?

K

Knute Johnson

I found a strange compiler error when writing the code below. The next
program compiles and runs fine. In fact if I replace the error line
with the null statement it compiles just fine or if I just put the
braces around the error line it compiles. Needless to say, this has
been driving me nuts all morning!

Win XP Pro SP2
JDK 1.6.0-rc build 103

I haven't tried it on an older compiler.

Any ideas?

Thanks,

knute...


import java.util.*;

public class test1 {
public static void main(String[] args) throws Exception {
Hashtable<Integer,String[]> hash =
new Hashtable<Integer,String[]>();
hash.put(1,new String[] {"hello","world"});
hash.put(2,new String[] {"good","bye"});

for (Enumeration<Integer> e=hash.keys(); e.hasMoreElements();)
String[] array = hash.get(e.nextElement()); // <---- error
}
}

C:\com\knutejohnson\redrock\scores>javac test1.java
test1.java:10: '.class' expected
String[] array = hash.get(e.nextElement());
^
test1.java:10: not a statement
String[] array = hash.get(e.nextElement());
^
2 errors


import java.util.*;

public class test1 {
public static void main(String[] args) throws Exception {
Hashtable<Integer,String[]> hash =
new Hashtable<Integer,String[]>();
hash.put(1,new String[] {"hello","world"});
hash.put(2,new String[] {"good","bye"});

for (Enumeration<Integer> e=hash.keys(); e.hasMoreElements();) {
String[] array = hash.get(e.nextElement());
for (int i=0; i<array.length; i++)
System.out.println(array);
}
}
}
 
R

Richard F.L.R.Snashall

Knute said:
In fact if I replace the error line
with the null statement it compiles just fine or if I just put the
braces around the error line it compiles.

And your aversion to braces is???
 
D

Daniel Pitts

Knute said:
I found a strange compiler error when writing the code below. The next
program compiles and runs fine. In fact if I replace the error line
with the null statement it compiles just fine or if I just put the
braces around the error line it compiles. Needless to say, this has
been driving me nuts all morning!

Win XP Pro SP2
JDK 1.6.0-rc build 103

I haven't tried it on an older compiler.

Any ideas?

Thanks,

knute...


import java.util.*;

public class test1 {
public static void main(String[] args) throws Exception {
Hashtable<Integer,String[]> hash =
new Hashtable<Integer,String[]>();
hash.put(1,new String[] {"hello","world"});
hash.put(2,new String[] {"good","bye"});

for (Enumeration<Integer> e=hash.keys(); e.hasMoreElements();)
String[] array = hash.get(e.nextElement()); // <---- error
}
}

C:\com\knutejohnson\redrock\scores>javac test1.java
test1.java:10: '.class' expected
String[] array = hash.get(e.nextElement());
^
test1.java:10: not a statement
String[] array = hash.get(e.nextElement());
^
2 errors


import java.util.*;

public class test1 {
public static void main(String[] args) throws Exception {
Hashtable<Integer,String[]> hash =
new Hashtable<Integer,String[]>();
hash.put(1,new String[] {"hello","world"});
hash.put(2,new String[] {"good","bye"});

for (Enumeration<Integer> e=hash.keys(); e.hasMoreElements();) {
String[] array = hash.get(e.nextElement());
for (int i=0; i<array.length; i++)
System.out.println(array);
}
}
}

You can't declare a variable in a one-statement block.
if (true) int something=10; // fails
if (true) { int something=10; } // succeeds.

Also, why not use HashMap?
Map<Integer, String[]> hash = new HashMap<Integer, String[]>();
// Do something with hash
for (Map.Entry<Integer, String[]> entry : hash.entrySet()) {
System.out.print(entry.getKey() + "->{");
for (String string : entry.getValue()) {
System.out.print(string + ", ");
}
System.out.println("}");
}
 
O

Oliver Wong

Richard F.L.R.Snashall said:
And your aversion to braces is???

I think the problem isn't so much "How can I get this to compile?" but
rather "What's wrong with my understanding of the Java language?".

- Oliver
 
R

Richard F.L.R.Snashall

Oliver said:
I think the problem isn't so much "How can I get this to compile?" but
rather "What's wrong with my understanding of the Java language?".

So it's as simple as "a declarator block requires braces"?
 
P

Patricia Shanahan

Knute Johnson wrote:
....
for (Enumeration<Integer> e=hash.keys(); e.hasMoreElements();)
String[] array = hash.get(e.nextElement()); // <---- error
....

You are confusing two very different entities, a statement and a
variable declaration.

The for MUST be followed by a statement.

You have a local variable declaration, which is not itself a statement
but can appear in a compound statement, such as a brace-enclosed block.

Incidentally, it seems a bit pointless because you assign to array and
then immediately leave its scope of declaration.
C:\com\knutejohnson\redrock\scores>javac test1.java
test1.java:10: '.class' expected
String[] array = hash.get(e.nextElement());
^
test1.java:10: not a statement
String[] array = hash.get(e.nextElement());
^
2 errors

The first error message shows what happened when the compiler tried to
interpret the first few tokens as a statement, not a declaration.
"String[]" is not very likely as the start of a statement, but it could
have been something like "String[].class.notifyAll();". Not finding
".class" killed that idea.

The second message points out that it is not a statement, which is the
real problem.

Patricia
 
A

aldeabtalal

Patricia said:
Knute Johnson wrote:
...
for (Enumeration<Integer> e=hash.keys(); e.hasMoreElements();)
String[] array = hash.get(e.nextElement()); // <---- error
...

You are confusing two very different entities, a statement and a
variable declaration.

The for MUST be followed by a statement.

You have a local variable declaration, which is not itself a statement
but can appear in a compound statement, such as a brace-enclosed block.

Incidentally, it seems a bit pointless because you assign to array and
then immediately leave its scope of declaration.
C:\com\knutejohnson\redrock\scores>javac test1.java
test1.java:10: '.class' expected
String[] array = hash.get(e.nextElement());
^
test1.java:10: not a statement
String[] array = hash.get(e.nextElement());
^
2 errors

The first error message shows what happened when the compiler tried to
interpret the first few tokens as a statement, not a declaration.
"String[]" is not very likely as the start of a statement, but it could
have been something like "String[].class.notifyAll();". Not finding
".class" killed that idea.

The second message points out that it is not a statement, which is the
real problem.

Patricia
 
O

Oliver Wong

Richard F.L.R.Snashall said:
So it's as simple as "a declarator block requires braces"?

Or that a variable declaration is not considered a statement (something
I didn't know either, until now). I don't think the OP had any doubts that
blocks require braces.

- Oliver
 
K

Knute Johnson

Patricia said:
Knute Johnson wrote:
...
for (Enumeration<Integer> e=hash.keys(); e.hasMoreElements();)
String[] array = hash.get(e.nextElement()); // <---- error
...

You are confusing two very different entities, a statement and a
variable declaration.

The for MUST be followed by a statement.

You have a local variable declaration, which is not itself a statement
but can appear in a compound statement, such as a brace-enclosed block.

I understand the issue here I just can't find in the JLS where it is not
a statement. In fact, JLS 14.4.4 Execution of Local Variable
Declarations "A local variable declaration statement is an executable
statement.", would seem to say otherwise.
Incidentally, it seems a bit pointless because you assign to array and
then immediately leave its scope of declaration.
Yes.
C:\com\knutejohnson\redrock\scores>javac test1.java
test1.java:10: '.class' expected
String[] array = hash.get(e.nextElement());
^
test1.java:10: not a statement
String[] array = hash.get(e.nextElement());
^
2 errors

The first error message shows what happened when the compiler tried to
interpret the first few tokens as a statement, not a declaration.
"String[]" is not very likely as the start of a statement, but it could
have been something like "String[].class.notifyAll();". Not finding
".class" killed that idea.

The second message points out that it is not a statement, which is the
real problem.

Patricia

I think I found it - 14.4 Local Variable Declaration Statements
"Every local variable declaration statement is immediately contained by
a block. Local variable declaration statements may be intermixed freely
with other kinds of statements in the block."

This is a pretty subtle distinction but I can see the light now.

I can't think of a real situation where you would not have other code
mixed with the local variable declaration. Since you would then need an
enclosing block the error would never occur.

Thanks,
 
P

Patricia Shanahan

Knute said:
Patricia said:
Knute Johnson wrote:
...
for (Enumeration<Integer> e=hash.keys(); e.hasMoreElements();)
String[] array = hash.get(e.nextElement()); // <---- error
...

You are confusing two very different entities, a statement and a
variable declaration.

The for MUST be followed by a statement.

You have a local variable declaration, which is not itself a statement
but can appear in a compound statement, such as a brace-enclosed block.

I understand the issue here I just can't find in the JLS where it is not
a statement. In fact, JLS 14.4.4 Execution of Local Variable
Declarations "A local variable declaration statement is an executable
statement.", would seem to say otherwise.

ASCII does not work well for some of this, because it lacks distinct
fonts. Also I should have capitalized "Statement". I meant the syntax
element "Statement", not the English word "statement".

Section 14.5 Statements lists all the productions for the syntax element
Statement. It does not include the syntax element
LocalVariableDeclarationStatement.

The production:

IfThenStatement:
if ( Expression ) Statement

definitely requires a syntax element Statement.

Patricia
 
R

Red Orchid

Message-ID: said:
Knute Johnson wrote:
...
for (Enumeration<Integer> e=hash.keys(); e.hasMoreElements();)
String[] array = hash.get(e.nextElement()); // <---- error
...

You are confusing two very different entities, a statement and a
variable declaration.

The for MUST be followed by a statement.

You have a local variable declaration, which is not itself a statement
but can appear in a compound statement, such as a brace-enclosed block.

Incidentally, it seems a bit pointless because you assign to array and
then immediately leave its scope of declaration.



#0: "for ( ... ) a declaration statement;"

For a moment, let's consider the above '#0' not to be an error.
Now,
Let's take all possible cases into account.

Case 1)
#1_e:
for (...) int i = 0;

#1_c:
for (...) { int i = 0; }


Both '#1_e' and '#1_c' are useless because 'i' is never
read and '0' is constant.


Case 2)
#2_e:
for (...) int i = parse(...);

#2_c:
for (...) { int i = parse(...); }


Both '#2_e' and '#2_c' are not useless because 'parse(...)'
can change the state of some instances (ex: fields).


Case 3)
#3_e:
for (...) parse(...);

#3_c:
for (...) { parse(...); }

Both '#3_e' and '#3_c' are not useless.


From this point of view, '#*_e' are equivalent to '#*_c' .
But,
'#*_e' are errors and '#*_c' do not.

Is it valid that '#*_c' do not be errors ?
If so, what is the advantage of it ?


"Type name = ... ;" is composed of more than one statements
like a brace-enclosed block.

I think that it is unartificial that a compiler give warnings
about '#*_e', not errors.
 
S

Stefan Ram

Patricia Shanahan said:
ASCII does not work well for some of this, because it lacks
distinct fonts.

I assume that your intention was not to refer to the encoding
of ASCII but to the format "plain text", which does not allow
markup.

ASCII is an encoding for the ASCII character set.
Your post was encoded in ISO-8859-1, but you are free to
choose UTF-8. Still, you would not have "distinct fonts",
because it still would be "plain text".
Section 14.5 Statements lists all the productions for the
syntax element Statement. It does not include the syntax
element LocalVariableDeclarationStatement.

I like to have this semantic distinction:
A /declaration/ has its effect at compile time,
while a /statement/ has its effect at run time.
Naming a declaration a "statement" would blur this distinction.
 
P

Patricia Shanahan

Stefan said:
I assume that your intention was not to refer to the encoding
of ASCII but to the format "plain text", which does not allow
markup.

ASCII is an encoding for the ASCII character set.
Your post was encoded in ISO-8859-1, but you are free to
choose UTF-8. Still, you would not have "distinct fonts",
because it still would be "plain text".
Correct.


I like to have this semantic distinction:
A /declaration/ has its effect at compile time,
while a /statement/ has its effect at run time.
Naming a declaration a "statement" would blur this distinction.

The distinction is inherently blurred in Java because of initializers.

An initializer has many of the characteristics of an executable
statement. It has to be given a place in the execution sequence, to
define the values of variables it uses and which computations are
affected by its side effects.

Patricia
 
K

Knute Johnson

Patricia said:
Knute said:
Patricia said:
Knute Johnson wrote:
...
for (Enumeration<Integer> e=hash.keys(); e.hasMoreElements();)
String[] array = hash.get(e.nextElement()); // <---- error
...

You are confusing two very different entities, a statement and a
variable declaration.

The for MUST be followed by a statement.

You have a local variable declaration, which is not itself a statement
but can appear in a compound statement, such as a brace-enclosed block.

I understand the issue here I just can't find in the JLS where it is
not a statement. In fact, JLS 14.4.4 Execution of Local Variable
Declarations "A local variable declaration statement is an executable
statement.", would seem to say otherwise.

ASCII does not work well for some of this, because it lacks distinct
fonts. Also I should have capitalized "Statement". I meant the syntax
element "Statement", not the English word "statement".

Section 14.5 Statements lists all the productions for the syntax element
Statement. It does not include the syntax element
LocalVariableDeclarationStatement.

The production:

IfThenStatement:
if ( Expression ) Statement

definitely requires a syntax element Statement.

Patricia

Patricia:

So do you think this was an arbitrary distinction or is there some
reason that a LocalVariableDeclarationStatement had to be immediately
contained by a block (read that braces). Is it because of the
possibility of multiple execution within the containing block of a 'for'
or other loop?

I found this by accident debugging some code. It would probably never
come up in normal usage. I do find I learn a lot about the subtleties
of the language though when you answer my questions.

Thanks,
 
P

Patricia Shanahan

Knute Johnson wrote:
....
So do you think this was an arbitrary distinction or is there some
reason that a LocalVariableDeclarationStatement had to be immediately
contained by a block (read that braces). Is it because of the
possibility of multiple execution within the containing block of a 'for'
or other loop?
....

No, I think it may be because of the sheer logic of what a declaration is.

My first thought was something like "Well, they could act as though
every statement were in braces of its own, so it can function as block",
but that does not work for declarations:

{
int a = 3;
System.out.println(a);
}

is different from:

{
{int a = 3;}
{System.out.println(a);}
}

The language can't get away with wrapping implicit blocks around
declarations. They have to be written by the programmer, or there is a
risk of messing up scope.

Also, there is a human factors issue. A declaration by itself after an
"if" is at least as likely to be due to missing braces, and the first
line of a longer block, than to be intentional.

Patricia
 
K

Knute Johnson

Patricia said:
Knute Johnson wrote:
...
...

No, I think it may be because of the sheer logic of what a declaration is.

My first thought was something like "Well, they could act as though
every statement were in braces of its own, so it can function as block",
but that does not work for declarations:

{
int a = 3;
System.out.println(a);
}

is different from:

{
{int a = 3;}
{System.out.println(a);}
}

The language can't get away with wrapping implicit blocks around
declarations. They have to be written by the programmer, or there is a
risk of messing up scope.

Also, there is a human factors issue. A declaration by itself after an
"if" is at least as likely to be due to missing braces, and the first
line of a longer block, than to be intentional.

Patricia

Thanks Patricia.
 
L

Lew

Red said:
Message-ID: said:
Knute Johnson wrote:
...
for (Enumeration<Integer> e=hash.keys(); e.hasMoreElements();)
String[] array = hash.get(e.nextElement()); // <---- error
...

You are confusing two very different entities, a statement and a
variable declaration.

The for MUST be followed by a statement.

You have a local variable declaration, which is not itself a statement
but can appear in a compound statement, such as a brace-enclosed block.

Incidentally, it seems a bit pointless because you assign to array and
then immediately leave its scope of declaration.



#0: "for ( ... ) a declaration statement;"

For a moment, let's consider the above '#0' not to be an error.
Now,
Let's take all possible cases into account.

Case 1)
#1_e:
for (...) int i = 0;

#1_c:
for (...) { int i = 0; }


Both '#1_e' and '#1_c' are useless because 'i' is never
read and '0' is constant.


Case 2)
#2_e:
for (...) int i = parse(...);

#2_c:
for (...) { int i = parse(...); }


Both '#2_e' and '#2_c' are not useless because 'parse(...)'
can change the state of some instances (ex: fields).


Case 3)
#3_e:
for (...) parse(...);

#3_c:
for (...) { parse(...); }

Both '#3_e' and '#3_c' are not useless.


From this point of view, '#*_e' are equivalent to '#*_c' .
But,
'#*_e' are errors and '#*_c' do not.

Is it valid that '#*_c' do not be errors ?
If so, what is the advantage of it ?


"Type name = ... ;" is composed of more than one statements
like a brace-enclosed block.

I think that it is unartificial that a compiler give warnings
about '#*_e', not errors.

The Java(tm) language is what it is and it ain't what it ain't.

- Lew
 
P

Patricia Shanahan

Red Orchid wrote:
....
Case 2)
#2_e:
for (...) int i = parse(...);

#2_c:
for (...) { int i = parse(...); }


Both '#2_e' and '#2_c' are not useless because 'parse(...)'
can change the state of some instances (ex: fields).

However, making them variable declarations rather than expression
statements is useless. All side effects of 'parse(...)' happen for

for (...)
parse(...);

Patricia
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top