No, the JLS specifically prohibits compilers from complaining that this code is unreachable. The idea is that you might have a constant boolean field, such as
And later code like
By changing the value of DEBUG, you can control whether the println() is activated or not. But if the compiler were to complain that the println() is unreachable (since it knows DEBUG is false) then you'd be forced to remove this code, which would be annoying.
Nowadays code like this would probably be replaced with some sort of configurable logger. But at the time Java first came out, C/C++ were used to using preprocessor directives like
Java doesn't have preprocessor directives like C, but they left a few language features which emulate common C idioms, like this one.
As an example, suppose you have an abstract class that holds static final constants:
ClientGlobals.ENABLE_THIS_FEATURE is resolved at compile time, and the compiler in effect does a search and replace. Some clients may have this feature switched on and some switched off.
Joined: Sep 22, 2004
still a bit confused. my reasoning is I have set the actual value of false. I understand if I use a constant or even a variable and that is not set until runtime. Could you guys elaborate.
Joined: Jan 30, 2000
As far as the compiler is concerned, there is very little difference between
(provided DEBUG is defined as a complie-time constant with value false). The people who wrote the JLS had already made a special case for how to treat a compile-time constant represented as a variable (DEBUG); they didn't consider it worth their while to make a separate, different case for how to treat a compile-time constant represented as a literal. Basically, the few times someone actually wants to write something like "if (false)", the compiler assumes they meant to write that, and it's not worthwhile making the compiler complain about it.
Ultimately, someone made this decision long ago, when the language was still being developed, and they put the decision into the language specification. It may not make perfect sense, but there's no compelling reason tochange it - it doesn't actually interfere with anyone's ability to write code.
If you want a general rule, javac only evaluates constant expressions, including literals, when necessary in order to generate the byte code. Examples are array dimensions and case expressions.
Otherwise, it's strictly don't ask don't tell.
Examples are your "if(false)...;" and "k=j/0;". Besides allowing conditional debug output code, another good reason is to let students generate exceptions without playing games.
On the other hand, javac takes type safety as far as it possibly can. A good example is the instanceof operator, where an expression with instanceof that could never be true (the lefthand operand's type could never refer to an object that is assignment compatible with the right operand) causes a compile error. "Integer i; if(i instanceof String);" fails to compile.
[ December 22, 2004: Message edited by: Mike Gershman ] [ December 22, 2004: Message edited by: Mike Gershman ]