Stranger compiler error?

Discussion in 'Java' started by Knute Johnson, Nov 10, 2006.

  1. 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);
    }
    }
    }

    --

    Knute Johnson
    email s/nospam/knute/
     
    Knute Johnson, Nov 10, 2006
    #1
    1. Advertising

  2. Knute Johnson wrote:
    > 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???
     
    Richard F.L.R.Snashall, Nov 10, 2006
    #2
    1. Advertising

  3. Knute Johnson

    Daniel Pitts Guest

    Knute Johnson wrote:
    > 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);
    > }
    > }
    > }
    >
    > --
    >
    > Knute Johnson
    > email s/nospam/knute/

    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("}");
    }
     
    Daniel Pitts, Nov 10, 2006
    #3
  4. Knute Johnson

    Oliver Wong Guest

    "Richard F.L.R.Snashall" <> wrote in message
    news:...
    > Knute Johnson wrote:
    >> 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???


    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
     
    Oliver Wong, Nov 10, 2006
    #4
  5. Oliver Wong wrote:
    > "Richard F.L.R.Snashall" <> wrote in message
    > news:...
    >> Knute Johnson wrote:
    >>> 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???

    >
    > 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"?
     
    Richard F.L.R.Snashall, Nov 10, 2006
    #5
  6. 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
     
    Patricia Shanahan, Nov 10, 2006
    #6
  7. Knute Johnson

    Guest

    Patricia Shanahan wrote:
    > 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
     
    , Nov 10, 2006
    #7
  8. Knute Johnson

    Oliver Wong Guest

    "Richard F.L.R.Snashall" <> wrote in message
    news:...
    > Oliver Wong wrote:
    >> "Richard F.L.R.Snashall" <> wrote in message
    >> news:...
    >>> Knute Johnson wrote:
    >>>> 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???

    >>
    >> 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"?


    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
     
    Oliver Wong, Nov 10, 2006
    #8
  9. Patricia Shanahan wrote:
    > 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,

    --

    Knute Johnson
    email s/nospam/knute/
     
    Knute Johnson, Nov 11, 2006
    #9
  10. Knute Johnson wrote:
    > Patricia Shanahan wrote:
    >> 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 Shanahan, Nov 11, 2006
    #10
  11. Knute Johnson

    Red Orchid Guest

    Patricia Shanahan <> wrote or quoted in
    Message-ID: <t755h.4869$>:

    >
    > 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.
     
    Red Orchid, Nov 11, 2006
    #11
  12. Knute Johnson

    Stefan Ram Guest

    Patricia Shanahan <> writes:
    >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.
     
    Stefan Ram, Nov 11, 2006
    #12
  13. Stefan Ram wrote:
    > Patricia Shanahan <> writes:
    >> 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".


    Correct.

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


    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
     
    Patricia Shanahan, Nov 11, 2006
    #13
  14. Patricia Shanahan wrote:
    > Knute Johnson wrote:
    >> Patricia Shanahan wrote:
    >>> 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,

    --

    Knute Johnson
    email s/nospam/knute/
     
    Knute Johnson, Nov 11, 2006
    #14
  15. 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
     
    Patricia Shanahan, Nov 12, 2006
    #15
  16. Patricia Shanahan wrote:
    > 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


    Thanks Patricia.

    --

    Knute Johnson
    email s/nospam/knute/
     
    Knute Johnson, Nov 12, 2006
    #16
  17. Knute Johnson

    Lew Guest

    Red Orchid wrote:
    > Patricia Shanahan <> wrote or quoted in
    > Message-ID: <t755h.4869$>:
    >
    >> 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
     
    Lew, Nov 12, 2006
    #17
  18. 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
     
    Patricia Shanahan, Nov 13, 2006
    #18
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Yan
    Replies:
    0
    Views:
    1,139
  2. Jack Wright
    Replies:
    5
    Views:
    628
    Shiv Kumar
    Jan 19, 2004
  3. Ram
    Replies:
    0
    Views:
    2,847
  4. Kevin Newman

    priveledged stranger?

    Kevin Newman, Jul 27, 2005, in forum: Javascript
    Replies:
    6
    Views:
    81
    Kevin Newman
    Jul 29, 2005
  5. Knute Johnson

    Stranger printer happenings?

    Knute Johnson, Feb 1, 2014, in forum: Java
    Replies:
    3
    Views:
    121
    Knute Johnson
    Feb 2, 2014
Loading...

Share This Page