2016-05-11 106 views
1

在Java是未修改方法變量,在一個Java靜態/實例方法優化

  1. 靜態方法final, 預選賽重新初始化每次缺
  2. 實例方法

如果回答爲1.或2.(或兩者)final限定符 允許Java執行優化並存儲方法 變量只有一次?

如果答案取決於變量的類型,哪種類型的 變量被優化/未優化?例如,String, int優化,而Map未優化?

爲了比較,Java的只能存儲靜態類變量 如

private static final String foo = "Teenage Mutant Ninja Turtle"; 

一次。澄清:問題是是否

1:

static SomeReturnValueOrVoid SomeMethod() { 
    // 1.a Not modified, is this reinitialized each method call? 
    String foo = "Teenage Mutant Ninja Turtle"; 

    // 1.b Marked final, is this reinitialized each method call? 
    final String bar = "Teenage Mutant Hero Turtle"; 
} 

2:

SomeReturnValueOrVoid SomeMethod() { // not static 
    // 2.a Not modified, is this reinitialized each method call? 
    String foo = "Teenage Mutant Ninja Turtle"; 

    // 2.b Marked final, is this reinitialized each method call? 
    final String bar = "Teenage Mutant Hero Turtle"; 
} 

相當於

3:

class SomeClass { 
    static final String foo = "Teenage Mutant Ninja Turtle"; 

    SomeReturnValueOrVoid SomeMethod() { 
     // Uses foo 
    } 

    static SomeReturnValueOrVoid SomeMethod() { 
     // Uses foo 
    } 

    ... 
} 
+0

字符串常量在編譯過程中被解析 – AdamSkywalker

+0

除'Map'之外的其他類型,如何在這種情況下處理? –

+0

如果您在方法內部創建新映射,無論它是否爲最終映射,它都會每次創建。 – AdamSkywalker

回答

3

不管是static方法還是final變量或兩者都沒有區別。局部變量的範圍意味着每次都會執行此分配(除了優化*之外)。

但是,當涉及到示例中的字符串時,字符串將來自string pool。所以每次都會發生作業,但他們都會參考相同的string實例。

*優化 - JIT compiler可以內聯這些值,因此每個解決方案可以與另一個解決方案一樣快地運行。所以你不應該嘗試微觀優化自己,除非你知道實際的性能問題。

+0

感謝提到字符串池,非常寶貴的知識。當然,不成熟的優化是萬惡之源。只是有一個好奇心。 –

1

在Java中未修改方法變量,缺乏決賽中,資格賽每次

(該方法被調用)重新初始化 - 當然他們,否則會被初始化。

我認爲你真正想問的是,這種初始化可以通過某種方式進行優化嗎?如果變量被分配了一個常數值,那麼是的; JIT編譯器可能完全刪除該變量,並用它的(已知常量)值替換對它的引用。

最終限定符是否允許Java執行優化並僅存儲方法變量一次?

編號A final -qualified局部變量不能有它的價值變化,但在方法的每次調用都有自己的變量副本,不同的實例可能爲同一final變量使用不同的值。考慮:

void someMethod() 
{ 
    final int number = new Random().nextInt(); 
} 

的值不能被程序執行期間只分配一次,因爲它每個被調用的方法時是不同的。

對本地變量的final修飾符對優化幾乎沒有或沒有直接影響。它只對變量做了什麼限制 - 對任何變量都可能遵循的限制,不管限制如何 - 這又會允許某些優化。如果優化器是值得的,那麼它將不會在乎變量是否被聲明爲final,而是會考慮它是否是有效的常量。

+0

當然!現在點擊了。我應該完全意識到這一點,因爲方法變量是線程安全的。 –

+0

@FilipAllberg對於其他變量,JIT不關心。除非你聲明一個變量volatile,或者執行一些強制它們同步的東西,編譯器可以自由地假定沒有其他線程修改任何變量。它可以避免多餘的加載和存儲。這是合理的,因爲沒有同步,易失性和朋友,Java存儲器模型中沒有可視性保證(這與硬件的行爲相對應;按照核心緩存來考慮)。 – maaartinus