Lew said:
Sure it is.
> You are essentially asking a telepathy question.
Because your esthetic is somehow offended by a rule that eliminates by
design a useless and possibly maintenance-damaging wart from programs
that are /supposed/ to be durable, you guys whine that it's
"inconvenient" and try to second-guess the intent of the designers.
But there's now at least one documented case where the standard *causes*
inconvenience. Right now you sometimes can't test a change or comment
out one line of code without commenting out a whole block of code
somewhere else, AND another line or two in other places, in a manner
that is somewhat awkward. For example one line in a try block being
commented out or a change there tested may require commenting out the
try line, some distance above, and an entire catch block below,
ultimately forming three disjoint pieces of code. Easy to miss that
these three commented-out regions should really be commented back in
together as a single unit later on. Also more work. Some other cases
like this are logically unavoidable: if you comment out a declaration
you will clearly need to comment out every use of the declaration. The
try...catch case is not inherently unavoidable this way. It occurs
because of an arguably-gratuitous "feature" of the standard rather than
inevitable logic. Declarations are also not as often commented out or
experimented with in this sort of manner. The only cases I've ever run
into that've annoyed me have involved try...catch and switch, the latter
when the cases become or stop being exhaustive and the default sometimes
needs commenting out.
A warning suffices to alert that this code is not polished enough for
release, as a general rule.
Also, vast amounts of dead code that confound maintenance programmers
take the form of entire methods and even whole classes that lie about
collecting dust. None of these seems to generate an error with the
javacs I've used. In the non-private case, the compiler can't be sure
the code won't be linked with code that calls these methods, though, so
there is nothing it can do. I do seem to recall private methods that
aren't used generating a warning with one, but not an error.
Requiring dead code to be commented out would be reasonable if it were
easy to do so without the problems described above for try...catch.
Default blocks and entire unused private methods are easy to comment out
because they are single contiguous chunks of code. Commenting out a
catch is another matter. Perhaps a compromise would be to allow a
nilpotent try block -- a try { stuff } with no catch or finally clauses.
I suppose a workaround is to have a dummy finally clause containing only
a comment on every try block that doesn't have a "real" finally clause.
Then you can comment out a catch block without a complaint, even if it's
the sole catch block. This saves commenting out the try line. It still
means commenting in or out the throw in the try body and the catch
clause as a unit, but at least you will generally get an obvious
reminder to keep them in synch as the throw without the catch will, in
many cases, result in the compiler complaining that it's not declared or
handled (checked exceptions not thrown by the method being edited) and
the catch without the throw will get the current dead-code complaint.
Dummy finally clauses seem ugly to me, though, and a way to clutter code
with unhelpful and gratuitous crud -- the exact sort of thing the
standard here is argued to be trying to reduce.
Another compromise would be to permit an empty catch clause for an
unthrown exception. Then you could comment out the catch block's innards
and again save having to comment out the try line.
Warnings make sense in all of these cases (any try with no catch or
finally blocks that contain actual code) both to catch this sort of
temporary hack before release so it can be removed or otherwise fixed
(e.g. by uncommenting code you forgot to uncomment-out in a catch block)
and to catch some unrelated and common bad coding practises, such as to
catch and discard actually-thrown exceptions without taking any action.
This last assumes that a shop has a policy of not shipping as final (or
even beta) any code that generates warnings, and likewise requires real
justification for every @SuppressWarning use in production code. I hope
that that is considered basic common sense in every Java shop though.
formal reasoning about the program would be
eaiser for the compiler if this became a language requirement.
This is just plain wrong. To support the current standard, the compiler
has to determine which code is provably-dead-by-static-analysis and then
complain if there is any dead code detectable in this manner. The formal
reasoning in question can be supported if the compiler allows dead code
at the cost of simply performing the same static analysis and then
ignoring whatever it detects to be dead code (other than to emit a
warning). In other words, the compiler is required by the standard to
perform the same analysis that is needed anyway. Formal reasoning is
exactly as easy (or hard) either way.
> The
language is defined by its very rules - accusing me of "circular"
reasoning by reference to those rules is specious.
Not when those rules themselves are the subject of discussion. If we
were discussing whether some construct was legal in current Java, appeal
to the rules would not only be valid but the obvious way to definitively
answer the question. But we were not; we were discussing whether or not
it is desirable to *change* one of those rules, and there arguing that
it's not because the rules are the rules amounts to declaring by fiat
that the status quo is invariably preferable to any change, without
proving this. Such an attitude would, if held by Sun itself, have us
still using the clunky for (Iterator x = y.iterator(); x.hasNext()

to
loop over collections. (And lacking the type-safe generics we now enjoy,
but I think less people are enamored of generics as of the new for loop.

)
The Java designers clearly felt that this was a fundamental and
important issue - the section on unreachable code is one of the most
detailed and rigorous in the JLS. Clearly they felt it was vitally
important, as you will discover if you read that part.
That is not in dispute. Whether they actually were correct is under
discussion, not whether they felt strongly that they were correct.
Now you apparently disagree with that reasoning. That is fine. But
that doesn't make you right
Nor does the existing wording of the JLS automatically make us wrong.
or change the fact that reachability is one
of the fundamental design points that make Java the language that it
is. Java is designed to avoid problems, not invite them, and to create
durable software that will be maintainable.
I fail to see how warnings don't suffice, given a reasonable policy of
not letting code that generates warnings (or use of @SuppressWarning to
hide problems instead of solely in the rare and necessary cases
involving interfacing generics to arrays or legacy ungenerified code)
get out of alpha until the causes of the warnings are gone.
Really the argument should be on the other side - why should unreachable
code be tolerated at all? There must be a name for the logical fallacy
that throws the burden of proof on the wrong party.
As far as I'm aware, there is none. Nor is there any clear indication
that the burden of proof *is* on the wrong party here. Nobody is
asserting anything here entirely without evidence; you've pointed to the
standard, while we've pointed to an annoyance we've observed in actual
practise that may warrant amending that standard. Reducing the error to
a warning for the specific case of a catch clause for an unthrown
exception would be a fairly narrow and specific change and doesn't seem
wholly unjustified.
Perhaps the issue will become moot with smarter IDEs. Eclipse is already
surprisingly smart about some things, and so is NetBeans. Before long it
might be able to automatically comment out a catch block for an
exception no longer thrown, comment out the try line if there are no
"live" catch or finally clauses, and comment these back in if one of the
exceptions becomes thrown again, recognizing commented-out try lines and
catch blocks as something to uncomment if a matching exception throw
suddenly (re)appears between the try and the catch in question.
Essentially it would just require it to fix dead-code errors itself by
commenting out the offending code and the "other end" of the same brace
structure if there is one, and fix unhandled-exception errors by finding
a commented out catch that can handle it and uncommenting it (and any
matching commented-out try line, the nearest above it and at the same
nesting level) if possible.
Even a manual comment-out-clause and uncomment-clause command pair that
is smart enough to balance braces would improve this case a lot.
And ultimately it probably IS easier and likelier for the IDEs to change
than the JLS to change. Then again, Java 7 is apparently in the works
and fairly radical changes like reified generics are being contemplated.
Now may be a time when JLS changes are a bit more feasible.
It remains to question whether the suggested change would be desirable.
I'm not 100% sure myself.