In c\c++
can define:
#ifndef <token>
/* code */
#else
/* code to include if the token is defined */
#endif
my question, is there a way to do it in java? (which is not defining a global static variable..) for example i want to run some code only in debug mode..
thanks!
The answer is No. Not in the sense that you mean.
The way you do this kind of thing in Java as follows:
private static final boolean flag = true; /* or false :-) */
if (flag) {
/* code */
} else {
/* different code */
}
Java doesn't have a preprocessor (like C and C++ do). However, the compiler will optimize away the unused branch of an if
statement like the above, PROVIDED that flag
is a compile-time constant expression. This is a limited form of conditional compilation. Note that the controlling flag
constant can be imported from a different class.
(IIRC, this behaviour is specified in the JLS ... which means that you can rely on any conforming Java compiler to do it.)
@Treebranch comments that "this" can cause code bloat.
If @Treebranch is talking about object code bloat, this is not true. If you do this right with flags/expressions that are compile-time constant expressions as defined by the JLS, then the compiler does not emit any bytecodes for the "conditionally excluded" source code. See @edalorso's answer.
If @Treebranch is are talking about source-code bloat, I agree. But you can say the same thing for #ifdef
conditional compilation. (Macros and #include
can be used to reduce source-code bloat ... but only at the cost of readability, maintainability, etc. And that was the reason that the Java designers refused to support any source-code preprocessing.)
Java has a better way of dealing with platform differences, functionality variations and so on: use dynamic binding. If having lots of different plugin classes in your JAR is a concern (bytecode bloat), deal with it by creating a different JAR file for each platform, or whatever.
The approach that suggest that use of final static boolean variable is the closest to that suggested feature because it is even optimized by the compiler. If the flag is set to false the bytecodes contained in the block are not even generated.
Let me show an example:
public class Optimized {
private static final boolean DEBUG = true;
public static void main(String[] args) {
if(DEBUG){
System.out.println("DEBUG enabled");
}
}
}
This generates the bytecodes
public class Optimized {
public Optimized();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String DEBUG enabled
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
}
But if we turn the flag off...
private static final boolean DEBUG = false;
The bytecodes look as follows
public class Optimized {
public Optimized();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: return
}
So, AFAIK, this is the closest you can get to a precompile directive in Java.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With