LapisSea LapisSea - 3 months ago 17
Java Question

Java constant expression related code optimization on compile

Here is a simple question about Java compile optimisation.

Is

final int CONSTANT_NUMBER="Foo Bar".length();


equal to

final int CONSTANT_NUMBER=7;


on compiling code or generally in performance aspect?

Answer

No the java compiler doesn't evaluate "Foo Bar".length() at compile time.

Consider these classes

public class ConstantCheck {

    final int CONSTANT_NUMBER = "Foo Bar".length();
}

and

public class ConstantCheck {

    final int CONSTANT_NUMBER = 7;
}

Using javap -v on the compiled .class file you can see, that the .length() call is kept:

The former results in

...

  final int CONSTANT_NUMBER;
    descriptor: I
    flags: ACC_FINAL

  public text.ConstantCheck();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: aload_0
         5: ldc           #2                  // String Foo Bar
         7: invokevirtual #3                  // Method java/lang/String.length:()I
        10: putfield      #4                  // Field CONSTANT_NUMBER:I
        13: return
...

the latter in

...

  final int CONSTANT_NUMBER;
    descriptor: I
    flags: ACC_FINAL
    ConstantValue: int 7

  public text.ConstantCheck();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: aload_0
         5: bipush        7
         7: putfield      #2                  // Field CONSTANT_NUMBER:I
        10: return
    ....

In the first case the .length call is present

7: invokevirtual #3                  // Method java/lang/String.length:()I

in the second case it's just a constant that is written to the field

5: bipush        7
7: putfield      #2                  // Field CONSTANT_NUMBER:I