Final static variables operations, compile or runtime?

前端 未结 2 2099
名媛妹妹
名媛妹妹 2020-12-19 17:56

Do final static variables operations happen in run-time or compile time ? For example:

public static final int ID_1 = 1;
public static final int ID_2 = 2;

p         


        
相关标签:
2条回答
  • 2020-12-19 18:18

    There is a hint here: https://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html

    It says:

    If a primitive type or a string is defined as a constant and the value is known at compile time, the compiler replaces the constant name everywhere in the code with its value.

    So once that is done and you end up with 1 + 2 in the method, it would be logical for that to be optimized as well and just use the 3 at compile time.

    To prove it in practice, you can compile your code and then decompile it to see what's going on.

    I tried with JD-GUI and this is what I got when decompiling your code:

        public class TestCompileOrRuntime
        {
          public static final int ID_1 = 1;
          public static final int ID_2 = 2;
    
          public static int test()
          {
            return 3;
          }
        }
    

    So it looks in this case the compiler is solving the operation in compile time.

    0 讨论(0)
  • 2020-12-19 18:20

    It's a compile time operation (I get a method local iconst_3 below). We can directly examine the generated bytecode with javap -v. I created a class Main like,

    package com.stackoverflow;
    
    public class Main {
        public static final int ID_1 = 1;
        public static final int ID_2 = 2;
    
        public static int test() {
            return ID_1 + ID_2; // <-- Compile time.
        }
    }
    

    and then ran javap -v to get

    Classfile /home/efrisch/workspace/StackOverflow/bin/com/stackoverflow/Main.class
      Last modified Aug 22, 2015; size 410 bytes
      MD5 checksum 6ba30603e8f16cbebc681a84061d38c3
      Compiled from "Main.java"
    public class com.stackoverflow.Main
      minor version: 0
      major version: 52
      flags: ACC_PUBLIC, ACC_SUPER
    Constant pool:
       #1 = Class              #2             // com/stackoverflow/Main
       #2 = Utf8               com/stackoverflow/Main
       #3 = Class              #4             // java/lang/Object
       #4 = Utf8               java/lang/Object
       #5 = Utf8               ID_1
       #6 = Utf8               I
       #7 = Utf8               ConstantValue
       #8 = Integer            1
       #9 = Utf8               ID_2
      #10 = Integer            2
      #11 = Utf8               <init>
      #12 = Utf8               ()V
      #13 = Utf8               Code
      #14 = Methodref          #3.#15         // java/lang/Object."<init>":()V
      #15 = NameAndType        #11:#12        // "<init>":()V
      #16 = Utf8               LineNumberTable
      #17 = Utf8               LocalVariableTable
      #18 = Utf8               this
      #19 = Utf8               Lcom/stackoverflow/Main;
      #20 = Utf8               test
      #21 = Utf8               ()I
      #22 = Utf8               SourceFile
      #23 = Utf8               Main.java
    {
      public static final int ID_1;
        descriptor: I
        flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
        ConstantValue: int 1
    
      public static final int ID_2;
        descriptor: I
        flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
        ConstantValue: int 2
    
      public com.stackoverflow.Main();
        descriptor: ()V
        flags: ACC_PUBLIC
        Code:
          stack=1, locals=1, args_size=1
             0: aload_0
             1: invokespecial #14                 // Method java/lang/Object."<init>":()V
             4: return
          LineNumberTable:
            line 4: 0
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                0       5     0  this   Lcom/stackoverflow/Main;
    
      public static int test();
        descriptor: ()I
        flags: ACC_PUBLIC, ACC_STATIC
        Code:
          stack=1, locals=0, args_size=0
             0: iconst_3
             1: ireturn
          LineNumberTable:
            line 9: 0
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
    }
    SourceFile: "Main.java"
    
    0 讨论(0)
提交回复
热议问题