The Artima Developer Community
Sponsored Link

Chapter 8 of Inside the Java Virtual Machine
The Linking Model
by Bill Venners

<<  Page 11 of 20  >>

Advertisement

Compile-Time Resolution of Constants

As mentioned in Chapter 7, "The Lifetime of a Class," references to static final variables initialized to a compile-time constant are resolved at compile-time to a local copy of the constant value. This is true for constants of all the primitive types and of type java.lang.String.

This special treatment of constants facilitates two features of the Java language. First, local copies of constant values enable static final variables to be used as case expressions in switch statements. The two virtual machine instructions that implement switch statements in bytecodes, tableswitch and lookupswitch, require the case values in-line in the bytecode stream. These instructions do not support run-time resolution of case values. See Chapter 16, "Control Flow," for more information about these instructions.

The other motivation behind the special treatment of constants is conditional compilation. Java supports conditional compilation via if statements whose expressions resolve to a compile-time constant. Here's an example:

// On CD-ROM in file linking/ex2/AntHill.java
class AntHill {

    static final boolean debug = true;
}

// On CD-ROM in file linking/ex2/Example2.java
class Example2 {

    public static void main(String[] args) {
        if (AntHill.debug) {
            System.out.println("Debug is true!");
        }
    }
}

Because of the special treatment of primitive constants, the Java compiler can decide whether or not to include the body of the if statement in Example2.main() depending upon the value of AntHill.debug. Because AntHill.debug is true in this case, javac generates bytecodes for Example2's main() method that include the body of the if statement, but not a check of AntHill.debug's value. The constant pool of Example2 has no symbolic reference to class AntHill. Here are the bytecodes for main():

              // Push objref from System.out
0 getstatic #8 
              // Push objref to literal string "Debug is true!"
3 ldc #1 
              // Pop objref (to a String), pop objref(to
              // System.out), invoke println() on System.out
              // passing the string as the only parameter:
              // System.out.println("Debug is true!");
5 invokevirtual #9 
8 return      // return void

If the reference to AntHill.debug were resolved at run-time, the compiler would always need to include a check of AntHill.debug's value and the body of the if statement just in case value of AntHill.debug ever changed. The value of AntHill.debug can't change after it is compiled, of course, because it is declared as final. Still, you could change the source code of AntHill and recompile AntHill, but not recompile Example2.

Because the reference to AntHill.debug is resolved at compile-time the compiler can conditionally compile out the body of the if statement if AntHill.debug is discovered to be false. Note that this means you can't change the behavior of the Example2 application just be setting AntHill to false and recompiling only AntHill. You have to recompile Example2 as well.

Example3, shown below, is Example2 with its name changed to Example3 and compiled with an AntHill that has debug set to false:

// On CD-ROM in file linking/ex3/AntHill.java
class AntHill {

    static final boolean debug = false;
}

// On CD-ROM in file linking/ex3/Example3.java
class Example3 {

    public static void main(String[] args) {
        if (AntHill.debug) {
            System.out.println("Debug is true!");
        }
    }
}

Here are the bytecodes generated by javac for Example3's main() method:

0 return     // return void

As you can see, the Java compiler has brazenly eliminated the entire if statement found in Example3.main(). There is not even a hint of the println() invocation in this very short bytecode sequence.

<<  Page 11 of 20  >>


Sponsored Links



Google
  Web Artima.com   
Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use