Java編譯時常量和運行時常量


Java編譯時常量和運行時常量

編譯期常量指的就是程序在編譯時就能確定這個常量的具體值。

非編譯期常量就是程序在運行時才能確定常量的值,因此也稱為運行時常量。

在Java中,編譯期常量指的是用final關鍵字修飾的基本類型或String類型並直接賦值(非復雜運算)的變量(無論是否用static修飾),是編譯器的一種優化,體現在字節碼文件中;運行是常量是由運行時解釋器解釋完成的

運行時常量很容易理解,接下來會簡單的結合字節碼文件來介紹編譯時常量及使用風險。

public class ConstantTest {
    public final int a = 1;     //編譯時常量
    public final int b = 1+2;   //編譯時常量 支持加減乘除等簡單運算
    public final int c = b+3;   //編譯時常量 
    public final static int d = 10;   //編譯時常量 
    public final String str1 = "abc"; //編譯時常量 
    public final String str2 = "def" + "ghi";  //編譯時常量 支持字符串的連接
    public final String str3 = str2 + "jkl";  //編譯時常量 
    public final static String str4 = "static str";  //編譯時常量 
    public final double e = Math.random(); //運行時常量
    public final ConstantTest test = new ConstantTest(); //運行時常量
}

下面是編譯后相應的字節碼信息:

 

 注意!!!!!!

類B中所有引用類A中用static final修飾的靜態編譯時常量都會在編譯時全部替換為相應的數值或字符串,所以當修改了類A中的靜態編譯時常量時,類A和類B都要重新編譯,如果只重新編譯類A,則類B還是會引用之前的常量。

以下是案例:

類ConstantTest:

public class ConstantTest {
    public final int a = 1;     
    public final int b = 1+2;  
    public final int c = b+3;   
    public final static int d = 10;   
    public final String str1 = "abc"; 
    public final String str2 = "def" + "ghi";  
    public final String str3 = str2 + "jkl";  
    public final static String str4 = "static str";  
    public final double e = Math.random(); 
    public final ConstantTest test = new ConstantTest(); 
}

 類Test引用ConstantTest中的靜態編譯時常量:

public class Test{
    public int m = ConstantTest.d;
    public static int n = ConstantTest.d;
    public final int g = ConstantTest.d;
    public static final int j = ConstantTest.d;
    public static void main(String[] args) {
        int k = ConstantTest.d;
        System.out.println("m="+new Test().m);
        System.out.println("n="+n);
        System.out.println("g="+new Test().g);
        System.out.println("j="+j);
        System.out.println("k="+k);
    }
}

  首先全部編譯,運行Test類:

 

   修改ConstantTest中靜態常量的值為20后只重新編譯ConstantTest,運行結果:

 

   重新編譯Test后,運行結果:

 

  最后總結一下:

  1. 編譯期常量指的是用final關鍵字修飾的基本類型或String類型並直接賦值(非復雜運算)的變量(無論是否用static修飾);
  2. 運行時常量是程序在運行時才能確定值的一種常量;
  3. 所有引用其他類中靜態編譯時常量(一般就叫靜態常量,用static final修飾)的類在字節碼中全部替換為相應常量的值,所以引用靜態常量並不會觸發該類的的初始化。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM