why does catching errors that aren't thrown give syntax errors?

Discussion in 'Java' started by yawnmoth, Feb 16, 2009.

  1. yawnmoth

    yawnmoth Guest

    public class Test01
    {
    public static void main() {
    try {} catch (java.io.IOException e) {}
    }
    }

    When I run that, I get the following:

    Test01.java:4: exception java.io.IOException is never thrown in body
    of corresponding try statement
    try {} catch (java.io.IOException e) {}
    ^
    1 error

    My question is... why? Giving a syntax error over this seems about
    as appropriate as giving a syntax error for "if (false)". In both
    cases, although it may not serve a lot of point in a finished product,
    it may be useful for debugging. If I comment out a line that may
    (conditionally) throw java.io.IOException, it's annoying having to
    comment out a whole slew of other lines, as well. Same thing for "if
    (false)". That's easier than commenting out the whole if statement
    (especially if there aren't any else's present).
    yawnmoth, Feb 16, 2009
    #1
    1. Advertising

  2. yawnmoth

    Arne Vajhøj Guest

    yawnmoth wrote:
    > public class Test01
    > {
    > public static void main() {
    > try {} catch (java.io.IOException e) {}
    > }
    > }
    >
    > When I run that, I get the following:
    >
    > Test01.java:4: exception java.io.IOException is never thrown in body
    > of corresponding try statement
    > try {} catch (java.io.IOException e) {}
    > ^
    > 1 error
    >
    > My question is... why? Giving a syntax error over this seems about
    > as appropriate as giving a syntax error for "if (false)". In both
    > cases, although it may not serve a lot of point in a finished product,
    > it may be useful for debugging. If I comment out a line that may
    > (conditionally) throw java.io.IOException, it's annoying having to
    > comment out a whole slew of other lines, as well. Same thing for "if
    > (false)". That's easier than commenting out the whole if statement
    > (especially if there aren't any else's present).


    The Java language was designed that way.

    http://java.sun.com/docs/books/jls/third_edition/html/statements.html#14.20

    <quote>
    It is a compile-time error if a catch clause catches checked exception
    type E1 but there exists no checked exception type E2 such that all of
    the following hold:

    * E2 <: E1
    * The try block corresponding to the catch clause can throw E2
    * No preceding catch block of the immediately enclosing try
    statement catches E2 or a supertype of E2.

    unless E1 is the class Exception.
    </quote>

    The reasons is most likely to avoid not needed catch statement in
    final code.

    And yes it can be irritating during development.

    But apparently the final code has gotten priority over nuisances
    for the developer.

    And I agree with that.

    Arne
    Arne Vajhøj, Feb 16, 2009
    #2
    1. Advertising

  3. yawnmoth wrote:
    > My question is... why? Giving a syntax error over this seems about
    > as appropriate as giving a syntax error for "if (false)".


    Well, |if (false)| is not a compile-time error.

    In any case, the short answer is that catching a non-thrown exception is
    a syntax error as prescribed by the JLS. But you're probably wondering
    why it is a syntax error.

    I can't claim to know what the Java developers were thinking, but I'm
    going to guess:

    Most forms of unreachable code are forbidden, probably with the intent
    of easing development by getting rid of code that appears to be called
    but is, in fact, never called. |if (false)| is specifically allowed on
    the pretext that debug-specific code would be run via an if-block like
    |if (Util.DEBUG)|, where Util.DEBUG is a static boolean variable.

    Catching non-thrown exceptions is probably an example of where the
    developers made a mistake, in hindsight.
    --
    Beware of bugs in the above code; I have only proved it correct, not
    tried it. -- Donald E. Knuth
    Joshua Cranmer, Feb 16, 2009
    #3
  4. Patricia Shanahan wrote:
    >
    > I don't know the actual reason, but that one does not justify the
    > choice. The compiler could handle an unreachable catch block in
    > either
    > of two ways, leave it in or optimize it out. Both are simple and
    > straightforward.
    >
    > In general, Java seems to me to have an inconsistent attitude to
    > unreachable code. It allows "if(false)" but prohibits sticking in an
    > early return, leaving unreachable code after it, as well as
    > prohibiting unreachable catch blocks.


    This is explained in the JLS. As a general rule Java forbids
    unreachable code. It makes the single exception of "if (false)",
    specifically to allow the inclusion of code which can be turned on for
    debugging.
    Mike Schilling, Feb 16, 2009
    #4
  5. yawnmoth

    Arne Vajhøj Guest

    Patricia Shanahan wrote:
    > Arne Vajhøj wrote:
    >> yawnmoth wrote:
    >>> public class Test01
    >>> {
    >>> public static void main() {
    >>> try {} catch (java.io.IOException e) {}
    >>> }
    >>> }
    >>>
    >>> When I run that, I get the following:
    >>>
    >>> Test01.java:4: exception java.io.IOException is never thrown in body
    >>> of corresponding try statement
    >>> try {} catch (java.io.IOException e) {}
    >>> ^
    >>> 1 error
    >>>
    >>> My question is... why? Giving a syntax error over this seems about
    >>> as appropriate as giving a syntax error for "if (false)". In both
    >>> cases, although it may not serve a lot of point in a finished product,
    >>> it may be useful for debugging. If I comment out a line that may
    >>> (conditionally) throw java.io.IOException, it's annoying having to
    >>> comment out a whole slew of other lines, as well. Same thing for "if
    >>> (false)". That's easier than commenting out the whole if statement
    >>> (especially if there aren't any else's present).

    >>
    >> The Java language was designed that way.

    > ...
    >> The reasons is most likely to avoid not needed catch statement in
    >> final code.
    >>
    >> And yes it can be irritating during development.
    >>
    >> But apparently the final code has gotten priority over nuisances
    >> for the developer.
    >>
    >> And I agree with that.

    >
    > I don't know the actual reason, but that one does not justify the
    > choice. The compiler could handle an unreachable catch block in either
    > of two ways, leave it in or optimize it out. Both are simple and
    > straightforward.


    Yes.

    But the code does not make sense from a production code perspective.

    To me it is a very good reason to give error on code that does
    not make sense - even though it would be easy to generate code
    for it.

    > In general, Java seems to me to have an inconsistent attitude to
    > unreachable code. It allows "if(false)" but prohibits sticking in an
    > early return, leaving unreachable code after it, as well as prohibiting
    > unreachable catch blocks.


    I agree that is inconsistent.

    Arne
    Arne Vajhøj, Feb 16, 2009
    #5
  6. Patricia Shanahan wrote:
    > Mike Schilling wrote:
    >> Patricia Shanahan wrote:
    >>> I don't know the actual reason, but that one does not justify the
    >>> choice. The compiler could handle an unreachable catch block in
    >>> either
    >>> of two ways, leave it in or optimize it out. Both are simple and
    >>> straightforward.
    >>>
    >>> In general, Java seems to me to have an inconsistent attitude to
    >>> unreachable code. It allows "if(false)" but prohibits sticking in
    >>> an
    >>> early return, leaving unreachable code after it, as well as
    >>> prohibiting unreachable catch blocks.

    >>
    >> This is explained in the JLS. As a general rule Java forbids
    >> unreachable code. It makes the single exception of "if (false)",
    >> specifically to allow the inclusion of code which can be turned on
    >> for debugging.
    >>
    >>

    >
    > Unfortunately, if(false) is not a good general solution to the
    > temporary code exclusion problem, because the code it excludes has
    > to
    > be a compilable statement (including a block statement).


    It's still possible to comment out code, but that has the problem that
    when you remove the comments, it's quite possible that the code no
    longer compiles (or never did.) I find the fact that the syntax is
    checked but no bytecode is generated to be a useful feature.
    Mike Schilling, Feb 16, 2009
    #6
  7. yawnmoth

    blue indigo Guest

    On Sun, 5647 Sep 1993 19:09:53 -0800, Joshua Cranmer wrote:

    > yawnmoth wrote:
    >> My question is... why? Giving a syntax error over this seems about
    >> as appropriate as giving a syntax error for "if (false)".

    >
    > Well, |if (false)| is not a compile-time error.


    What about wrapping the line that throws the exception in if (false)
    instead of commenting it out?

    If the catch clause is still an error in that case, then it really is
    quite perverse.

    --
    blue indigo
    UA Telecom since 1987
    blue indigo, Feb 16, 2009
    #7
  8. On 2009-02-16, blue indigo <> wrote:
    > On Sun, 5647 Sep 1993 19:09:53 -0800, Joshua Cranmer wrote:
    >
    >> yawnmoth wrote:
    >>> My question is... why? Giving a syntax error over this seems about
    >>> as appropriate as giving a syntax error for "if (false)".

    >>
    >> Well, |if (false)| is not a compile-time error.

    >
    > What about wrapping the line that throws the exception in if (false)
    > instead of commenting it out?
    >
    > If the catch clause is still an error in that case, then it really is
    > quite perverse.


    As I recall, allowing if(false) is more or less an intended idiom to
    act as a poor man's #ifdef. That is, you can write
    public final static boolean DEBUG = false;
    in some central place and then have
    if(DEBUG) { /* lots of debug reporting */ }
    all over the place that won't make it into the bytecode so long as
    DEBUG is false (saving space & cycles).

    Or perhaps that is more an evolved consequence of allowing if(false)
    then the original intention behind it, that I don't know.

    Catching non-thrown exceptions, however, is regarded as just being
    sloppy (or more likely confused) and so disallowed since we don't
    really want to have software written by sloppy or confused programmers
    out there.

    Cheers,
    Bent D
    --
    Bent Dalager - - http://www.pvv.org/~bcd
    powered by emacs
    Bent C Dalager, Feb 16, 2009
    #8
  9. yawnmoth

    Lew Guest

    On Feb 15, 10:38 pm, Patricia Shanahan <> wrote:
    > Arne Vajhøj wrote:
    > > yawnmoth wrote:
    > >> public class Test01
    > >> {
    > >>     public static void main() {
    > >>         try {} catch (java.io.IOException e) {}
    > >>     }
    > >> }

    >
    > >> When I run that, I get the following:

    >
    > >> Test01.java:4: exception java.io.IOException is never thrown in body
    > >> of corresponding try statement
    > >>         try {} catch (java.io.IOException e) {}
    > >>                ^
    > >> 1 error

    >
    > >> My question is...  why?  Giving a syntax error over this seems about
    > >> as appropriate as giving a syntax error for "if (false)".  In both
    > >> cases, although it may not serve a lot of point in a finished product,
    > >> it may be useful for debugging.  If I comment out a line that may
    > >> (conditionally) throw java.io.IOException, it's annoying having to
    > >> comment out a whole slew of other lines, as well.  Same thing for "if
    > >> (false)".  That's easier than commenting out the whole if statement
    > >> (especially if there aren't any else's present).

    >
    > > The Java language was designed that way.

    > ...
    > > The reasons is most likely to avoid not needed catch statement in
    > > final code.

    >
    > > And yes it can be irritating during development.

    >
    > > But apparently the final code has gotten priority over nuisances
    > > for the developer.

    >
    > > And I agree with that.

    >
    > I don't know the actual reason, but that one does not justify the
    > choice. The compiler could handle an unreachable catch block in either
    > of two ways, leave it in or optimize it out. Both are simple and
    > straightforward.
    >
    > In general, Java seems to me to have an inconsistent attitude to
    > unreachable code. It allows "if(false)" but prohibits sticking in an
    > early return, leaving unreachable code after it, as well as prohibiting
    > unreachable catch blocks.


    'if ( false )' was an intentional deviation to allow conditional
    compilation, and is explained as such in the JLS:
    > This approach would be consistent with the treatment of other control structures.
    > However, in order to allow the if statement to be used conveniently for
    > "conditional compilation" purposes, the actual rules differ.


    It isn't fair to use it as a model for other control structures. They
    acknowledge that it's different, they explain why it's different, they
    intended it to be different. Complaining then that it's different is
    silly.

    --
    Lew
    Lew, Feb 16, 2009
    #9
  10. yawnmoth

    Lew Guest

    On Feb 15, 9:29 pm, yawnmoth <> wrote:
    > public class Test01
    > {
    >     public static void main() {
    >         try {} catch (java.io.IOException e) {}
    >     }
    >
    > }
    >
    > When I run that, I get the following:
    >
    > Test01.java:4: exception java.io.IOException is never thrown in body
    > of corresponding try statement
    >         try {} catch (java.io.IOException e) {}
    >                ^
    > 1 error
    >
    > My question is...  why?  


    Because the JLS says so.

    --
    Lew
    Lew, Feb 16, 2009
    #10
  11. yawnmoth

    Tom Anderson Guest

    Re: why does catching errors that aren't thrown give syntaxerrors?

    On Sun, 15 Feb 2009, yawnmoth wrote:

    > public class Test01
    > {
    > public static void main() {
    > try {} catch (java.io.IOException e) {}
    > }
    > }
    >
    > When I run that, I get the following:
    >
    > Test01.java:4: exception java.io.IOException is never thrown in body
    > of corresponding try statement
    > try {} catch (java.io.IOException e) {}
    > ^
    > 1 error
    >
    > My question is... why? Giving a syntax error over this seems about
    > as appropriate as giving a syntax error for "if (false)".


    As others have said, it's because java won't let you write unreachable
    code. The risk would be in cases like:

    class FileAccessException extends Exception // *not* an IOException

    public void foo() throws FileAccessException { ... }

    try {
    foo();
    }
    catch (IOException e) {
    // the programmer thinks he'll deal with FileAccessException here,
    // but he won't, and that's the kind of thing that leads to bugs
    }

    Of course, the compiler would still insist on FileAccessException being
    handled here, but that's could still get dropped one way or another, once
    the programmer's got it in his head that he's dealing with it in that
    block.

    > In both cases, although it may not serve a lot of point in a finished
    > product, it may be useful for debugging. If I comment out a line that
    > may (conditionally) throw java.io.IOException, it's annoying having to
    > comment out a whole slew of other lines, as well. Same thing for "if
    > (false)". That's easier than commenting out the whole if statement
    > (especially if there aren't any else's present).


    Yes, it's a pain, isn't it. I've been annoyed by this in the past too.
    Could you get aikido on java and do something like:

    try {
    // otherwise empty block
    if (false) throw new IOException();
    }
    catch (IOException e) {
    // your catch code here
    }

    ?

    tom

    --
    solvilvitur ambulando. copy a diamond shape, recording angel. .. ..
    Tom Anderson, Feb 16, 2009
    #11
  12. yawnmoth

    Tom Anderson Guest

    Re: why does catching errors that aren't thrown give syntaxerrors?

    On Mon, 16 Feb 2009, Thomas Pornin wrote:

    > According to Tom Anderson <>:
    >> As others have said, it's because java won't let you write unreachable
    >> code.

    >
    > Note, though, that this particular check is performed by the compiler
    > only, whereas the prohibition of "dead code" is generally enforced by
    > the JVM during bytecode verification(*).


    [snip]

    That is some very interesting stuff - thanks! I had no idea that the
    validator was concerned with dead code - are you saying that it
    can/should/must reject bytecode with unreachable instructions?

    tom

    --
    Well, I'm making a list too. But I'm also preparing appropriate
    retribution. -- Graham
    Tom Anderson, Feb 17, 2009
    #12
  13. yawnmoth

    blue indigo Guest

    On Mon, 5643 Sep 1993 14:45:26 +0000, Bent C Dalager wrote:

    > On 2009-02-16, blue indigo <.> wrote:
    >> On Sun, 5647 Sep 1993 19:09:53 -0800, Joshua Cranmer wrote:
    >>> yawnmoth wrote:
    >>>> My question is... why? Giving a syntax error over this seems about
    >>>> as appropriate as giving a syntax error for "if (false)".
    >>>
    >>> Well, |if (false)| is not a compile-time error.

    >>
    >> What about wrapping the line that throws the exception in if (false)
    >> instead of commenting it out?
    >>
    >> If the catch clause is still an error in that case, then it really is
    >> quite perverse.

    >
    > As I recall, allowing if(false) is more or less an intended idiom to
    > act as a poor man's #ifdef.


    [rest snipped]

    That isn't quite an answer to my question, mate.

    --
    blue indigo
    UA Telecom since 1987
    blue indigo, Feb 17, 2009
    #13
  14. yawnmoth

    blue indigo Guest

    On Mon, 5643 Sep 1993 20:58:28 +0000, Tom Anderson wrote:

    > On Sun, 15 Feb 2009, yawnmoth wrote:
    >
    >> Test01.java:4: exception java.io.IOException is never thrown in body
    >> of corresponding try statement
    >>
    >> My question is... why?

    >
    > As others have said, it's because java won't let you write unreachable
    > code. The risk would be in cases like:
    >
    > class FileAccessException extends Exception // *not* an IOException
    >
    > public void foo() throws FileAccessException { ... }
    >
    > try {
    > foo();
    > }
    > catch (IOException e) {
    > // the programmer thinks he'll deal with FileAccessException here,
    > // but he won't, and that's the kind of thing that leads to bugs
    > }


    No problem, mate. The compiler will disabuse him of that notion right
    quick when it tells him "FileAccessException must be caught, or declared
    to be thrown" and points to the "foo()" line.


    --
    blue indigo
    UA Telecom since 1987
    blue indigo, Feb 17, 2009
    #14
  15. yawnmoth

    blue indigo Guest

    On Mon, 5643 Sep 1993 22:31:37 +0000, Thomas Pornin wrote:

    > Note, though, that this particular check is performed by the compiler
    > only, whereas the prohibition of "dead code" is generally enforced by
    > the JVM during bytecode verification(*).


    [snip]

    > Regardless of what the compiler thinks about exceptions, the JVM will
    > happily accept all of these because transgressions of the "checked
    > exceptions" rules do not impact the safety of the sandbox model that the
    > JVM implements.


    And transgressions of the "dead code" rules do? How?

    --
    blue indigo
    UA Telecom since 1987
    blue indigo, Feb 17, 2009
    #15
  16. yawnmoth

    blue indigo Guest

    On Mon, 5643 Sep 1993 07:49:08 -0800, Lew wrote:

    > On Feb 15, 9:29 pm, yawnmoth <> wrote:
    >> Test01.java:4: exception java.io.IOException is never thrown in body
    >> of corresponding try statement
    >>
    >> My question is...  why?  

    >
    > Because the JLS says so.


    The quality of your replies seems to me to be highly variable. Sometimes
    really useful and informative. Sometimes just a spelling flame or an
    apparently-irrelevant rant about top-posting or multi-posting with no
    content actually related to the question being asked. Sometimes feeding
    the trolls. And sometimes, like now, simply begging the question.

    --
    blue indigo
    UA Telecom since 1987
    blue indigo, Feb 17, 2009
    #16
  17. yawnmoth

    Arne Vajhøj Guest

    Lew wrote:
    > On Feb 15, 10:38 pm, Patricia Shanahan <> wrote:
    >> Arne Vajhøj wrote:
    >>> yawnmoth wrote:
    >>>> public class Test01
    >>>> {
    >>>> public static void main() {
    >>>> try {} catch (java.io.IOException e) {}
    >>>> }
    >>>> }
    >>>> When I run that, I get the following:
    >>>> Test01.java:4: exception java.io.IOException is never thrown in body
    >>>> of corresponding try statement
    >>>> try {} catch (java.io.IOException e) {}
    >>>> ^
    >>>> 1 error
    >>>> My question is... why? Giving a syntax error over this seems about
    >>>> as appropriate as giving a syntax error for "if (false)". In both
    >>>> cases, although it may not serve a lot of point in a finished product,
    >>>> it may be useful for debugging. If I comment out a line that may
    >>>> (conditionally) throw java.io.IOException, it's annoying having to
    >>>> comment out a whole slew of other lines, as well. Same thing for "if
    >>>> (false)". That's easier than commenting out the whole if statement
    >>>> (especially if there aren't any else's present).
    >>> The Java language was designed that way.

    >> ...
    >>> The reasons is most likely to avoid not needed catch statement in
    >>> final code.
    >>> And yes it can be irritating during development.
    >>> But apparently the final code has gotten priority over nuisances
    >>> for the developer.
    >>> And I agree with that.

    >> I don't know the actual reason, but that one does not justify the
    >> choice. The compiler could handle an unreachable catch block in either
    >> of two ways, leave it in or optimize it out. Both are simple and
    >> straightforward.
    >>
    >> In general, Java seems to me to have an inconsistent attitude to
    >> unreachable code. It allows "if(false)" but prohibits sticking in an
    >> early return, leaving unreachable code after it, as well as prohibiting
    >> unreachable catch blocks.

    >
    > 'if ( false )' was an intentional deviation to allow conditional
    > compilation, and is explained as such in the JLS:
    >> This approach would be consistent with the treatment of other control structures.
    >> However, in order to allow the if statement to be used conveniently for
    >> "conditional compilation" purposes, the actual rules differ.

    >
    > It isn't fair to use it as a model for other control structures. They
    > acknowledge that it's different, they explain why it's different, they
    > intended it to be different. Complaining then that it's different is
    > silly.


    Not if you are against exceptions to the general rules in the language.

    Arne
    Arne Vajhøj, Feb 17, 2009
    #17
  18. yawnmoth

    Lew Guest

    blue indigo wrote:
    > The quality of your replies seems to me to be highly variable. Sometimes
    > really useful and informative. Sometimes just a spelling flame or an
    > apparently-irrelevant rant about top-posting or multi-posting with no
    > content actually related to the question being asked. Sometimes feeding
    > the trolls. And sometimes, like now, simply begging the question.


    Thank you for your /ad hominem/ remarks.

    --
    Lew
    Lew, Feb 17, 2009
    #18
  19. yawnmoth

    blue indigo Guest

    On Mon, 16 Feb 2009 21:26:48 -0500, Lew wrote:

    > blue indigo wrote:
    >> The quality of your replies seems to me to be highly variable. Sometimes
    >> really useful and informative. Sometimes just a spelling flame or an
    >> apparently-irrelevant rant about top-posting or multi-posting with no
    >> content actually related to the question being asked. Sometimes feeding
    >> the trolls. And sometimes, like now, simply begging the question.

    >
    > Thank you for your /ad hominem/ remarks.


    It was intended as constructive criticism. As, I believe, are some of the
    posts you make that I characterized as spelling flames and similarly, but
    which maybe could be improved upon, for example by never neglecting the
    core point of the preceding post and sometimes by recognizing a lost cause
    (such as attempts to educate spammers and trolls).

    Perhaps you don't agree.

    Carry on, then.

    --
    blue indigo
    UA Telecom since 1987
    blue indigo, Feb 17, 2009
    #19
  20. yawnmoth

    Mark Space Guest

    Mike Schilling wrote:
    > Patricia Shanahan wrote:


    >> Unfortunately, if(false) is not a good general solution to the
    >> temporary code exclusion problem, because the code it excludes has
    >> to
    >> be a compilable statement (including a block statement).

    >
    > It's still possible to comment out code, but that has the problem that
    > when you remove the comments, it's quite possible that the code no
    > longer compiles (or never did.) I find the fact that the syntax is
    > checked but no bytecode is generated to be a useful feature.
    >
    >



    Also, back in the bad old days, commenting out code used to require /*
    and */. This was before C++ made the // style of single line comment
    popular.

    Unfortunately the /* */ failed if one tried to comment out a comment.
    So one used #if 0 or similar (#ifdef null). The if(false) construct is
    probably a stylistic hold-over from the early C days. This also has an
    advantage over // on each line in that it's easier to comment out large
    blocks of code. (Think: try doing that with a simple text editor. Ouch.)

    Just guessing though, of course.
    Mark Space, Feb 17, 2009
    #20
    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. Adam Maass
    Replies:
    5
    Views:
    395
    Sudsy
    Jul 22, 2003
  2. Mike Schilling
    Replies:
    2
    Views:
    344
    Mike Schilling
    Jul 16, 2003
  3. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,762
    Smokey Grindel
    Dec 2, 2006
  4. grocery_stocker
    Replies:
    10
    Views:
    612
    Keith Thompson
    May 25, 2005
  5. John Harkin
    Replies:
    0
    Views:
    142
    John Harkin
    Aug 18, 2004
Loading...

Share This Page