2011-05-13 53 views
-1

延遲實例聲明變量最終訴延遲實例

public class Foo{ 
    private NotSoExpensiveObject o; 

    public NotSoExpensiveObject getNSEObject(){ 
     if(o == null){ 
      o = new NotSoExpensiveObject(); 
     } 
     return o; 
    } 
} 

聲明最後

public class Foo{ 
    private final NotSoExpensiveObject o; 

    public Foo(){ 
     o = new NotSoExpensiveObject(); 
    } 
} 

是否宣佈NotSoExpensiveObject最終有超過延緩其實例什麼優勢?或者這是純粹的情景?另外,有沒有辦法延遲實例化,並保持final修飾符?

感謝

回答

1

聲明NotSoExpensiveObject 最終是否有過拖延 其實例什麼優勢?或者這純粹是情景嗎?阿爾斯

final將使不變,不可修改(即。CONST當量C,一旦你分配給它,你不能改變的值)。它無關,與懶動初始化

是有延遲的實例化,並保持final修飾符

也許在這裏你看到這個代碼的地方的方式欲養而不能以價值是非可修改等final

+1

你可能會在那裏不可修改的地方小心。它可能意味着一個可變對象變得不可修改。 – 2011-05-13 14:14:28

+0

@安德魯謝謝,增加更多信息 – 2011-05-13 14:17:51

1

最後只是一個編譯時間限制和因此這樣的決賽成員必須初始化內聯時,他們被聲明或在構造函數。當不同的構造函數需要以不同的方式初始化最後一個成員時,「延遲」最後是很好的。

+0

你是什麼意思_「延遲」final_?當我延遲它的實例化時,我不能聲明'NotSoExpensiveObject' final,雖然它基本上保證被每個'Foo'實例初始化一次。我想我真正好奇的是,如果給變量賦值'final'修飾符有任何性能好處...可能不會。 – mre 2011-05-13 14:17:03

+0

通過延遲我的意思是將值賦給構造函數中的最終成員而不是成員。 Final的不同用途有不同的性能差異,但如果使用final,則可能會有輕微的性能提升。 – 2011-05-13 14:19:15

+0

我雖然這隻適用於局部變量,並且您可以檢查Modifier.isFinal(myField)。我記得讀過,聲明類變量final有影響如何初始化,這可能會影響同步? – tofarr 2011-05-13 14:25:48

1

延遲實例化可能不是線程安全的,除非您進行同步。

+0

爲簡潔起見,我省略了同步,但是有效! – mre 2011-05-13 14:21:19

1

您的Foo類是從不同的線程使用的嗎?如果是,則需要將同步添加到惰性初始化解決方案。如果您使用了「最終」變體,則不必這樣做。在這種情況下,JVM保證對其他線程可見對NoSoExpensiveObject的引用。

也沒有辦法保留最終修飾符,仍然使用延遲初始化。最終成員需要立即或通過構造函數初始化。