亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Java 中如何處理靜態最終成員和靜態成員?

Java 中如何處理靜態最終成員和靜態成員?

MMTTMM 2022-06-23 19:31:58
我已經在 Stack Overflow 和網絡上的其他地方看到了一些關于靜態變量的內容。但是,我并不清楚答案。當我認為我找到了答案時,其他一些來源與該陳述相矛盾(或者至少,我認為確實如此)。例如:m0bius 告訴我們static 關鍵字在 Java 中是如何工作的?(在“何時創建此副本[編輯靜態變量]?”部分中)靜態變量是在運行時創建的。但是,如果我檢查https://en.wikipedia.org/wiki/Class_variable(“靜態成員變量和靜態成員函數”部分),它會告訴我在某些語言中會發生相反的情況,而在其他語言中也會發生同樣的情況。我的問題可以分為兩個不同的問題:在Java中,類的靜態變量是在運行時還是在編譯時創建的?在Java中,類的最終靜態變量是在運行時還是在編譯時創建的?我的意思是編譯時間與運行時間:編譯時間:編譯源代碼的時間(即創建 .class 文件的時間)運行時間:程序實際運行的時間一些代碼僅用于此問題:// MyClass.javapublic class MyClass {    public static int instances;    public final static double PI = 3.14159265359    public MyClass() {        instances++;    }    // ...}// Main.java ; version 1public class Main {    public static void main(String args[]) {        System.out.println("I am doing nothing with MyClass");    }}// OUTPUT: I am doing nothing with MyClass// Main.java ; version 2public class Main {    public static void main(String args[]) {        System.out.println("PI = " + MyClass.PI);        MyClass obj1 = new MyClass();        MyClass obj2 = new MyClass();        System.out.println("instances = " + MyClass.instances);    }}OUTPUT:3.141592653592如果靜態變量和最終靜態變量都在運行時創建,那么在 Main 的第一個版本中,MyClass 類的兩個靜態變量(實例和 PI)都不會創建。但我有點期望最終的靜態變量 PI 將在編譯時創建(因此它將被“嵌入”在 .class 文件中),因為我認為這會有更好的性能(無論類發生什么情況MyClass,PI 將始終為 3.14159265359,因此最好將其放入二進制文件中)。這可能與靜態變量相同,但它可能會在整個程序中發生變化。
查看完整描述

1 回答

?
莫回無

TA貢獻1865條經驗 獲得超7個贊

在Java中,類的靜態變量是在運行時還是在編譯時創建的?

Java 在編譯時沒有“創建”變量,如果創建意味著分配和初始化。它們都是在運行時創建的。它們是否static何時分配static final無關。

但我有點期望最終的靜態變量 PI 將在編譯時創建(因此它將被“嵌入”在 .class 文件中),因為我認為這會有更好的性能......

這不是它在 Java 中的工作方式。當類文件被“編譯”時,它們實際上主要是被編碼的。肯定有一些工作已經完成,但我們認為編譯的超大比例(就 C 等語言而言)是在運行時發生的。當我們查看優化和內聯時尤其如此。

如果可能的話,編譯器會做一些前期工作,例如能夠提前預先計算字段(靜態或實例)的值。例如,如果你像下面這樣定義你的字段,那么乘法將在編譯時完成:

private long timeoutMillis = 10 * 24 * 3600 * 1000;

對于 s 也是如此,String如果可能,編譯器會將常量字符串附加在一起。以下內容在運行時不使用 a StringBuilder,而是String在編譯時創建一個:

private static final String DEFAULT_HEADER = "A long headers that is " +   "broker into two lines\n";

但是,在這兩種情況下,字段( thelong timeoutMillis和 the String DEFAULT_HEADER)的分配和初始化都是在運行時完成的。

如果靜態變量和最終靜態變量都在運行時創建,那么在 Main 的第一個版本中,MyClass 類的兩個靜態變量(實例和 PI)都不會創建。

在您的示例中,第一次加載static類時分配和初始化字段(final或不) 。因此,在您的第一個or字段中,永遠不會像您提到的那樣創建。在你的第二個例子中。一旦被引用,類文件將被加載并創建字段。MaininstancesPI staticMyClassstatic


查看完整回答
反對 回復 2022-06-23
  • 1 回答
  • 0 關注
  • 141 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號