2012-03-13 51 views
2

在Java中,當爲final字段分配了常量值編譯時時,通常有意義的是聲明它爲static。它根據相關的PMD規則節省開銷。在GWT中使最終類變量保持靜態

在GWT中對生成的Javascript代碼做它有任何意義或區別嗎?

+1

你從哪裏讀到最終變量應該是靜態的?相反情況可能是正確的,因爲靜態變量通常是設計不佳的標誌,但最終得到非靜態變量是非常合理的 – 2012-03-13 14:44:24

+0

嗯,這是在我的代碼上檢查的PMD規則。見http://pmd.sourceforge.net/rules/design.html章節「FinalFieldCouldBeStatic」 – jabal 2012-03-13 15:02:20

+1

對不起,但您的文本是完全誤導。該規則指出,具有常數值的最終字段(如42)可以變爲靜態。它並不是說最終的變量應該是靜態的。這是個很大的差異! – 2012-03-13 15:54:10

回答

3

如果當它被聲明爲final的變量分配,然後是,靜態使一定量感,但也有情況下,它不應該是靜態的:

public MyClassWithFinal { 
    private final String finalVar; 
    public MyClassWithFinal(String name) { 
     this.finalVar = name; 
    } 
} 

另一種情況:如果實例var不是一個字符串或數字常量,但需要運行一個構造函數,該構造函數每次調用時都可能有副作用,因此只運行一次與運行多次不同。這就是說,GWT將內聯/內聯常量字符串值,所以如果你有多個字符串字段全部分配給相同的值,GWT可能會檢測到並將它們全部提升爲靜態。

public final String constant = "Some Constant that really ought to be static"; 

GWT會注意到,除非聲明,否則它將永遠不會被分配,甚至可能會刪除該字段本身。

最好的規則是從最好的(即最可讀的,最可維護的,最高效的)Java代碼開始,並且只有在GWT需要特定的東西的情況下才會突破。這不是這些情況之一:不管你如何編寫,編譯器都應該執行相同的基本優化。

+0

很好的答案,謝謝。所以你說對於原始類型例如字符串它是沒有意義的,由於GWT編譯器優化,對吧? – jabal 2012-03-13 15:07:10

+1

是和否:編譯器對於最終字段非常聰明,但是如果所有實例的內容始終相同,那麼可能意味着使用靜態 - 這就是我在最後一段中的意思,即使它最具可讀性。如果你真的想爲每個對象使用不同的字段實例,那麼就不要使用靜態的,但這些關鍵字不僅僅是編譯器的關鍵字,它們會向未來的代碼讀者傳達有用的信息。 – 2012-03-13 17:28:50

+1

答案中的第一個代碼塊是PMD不應該抱怨最終字符串字段的情況,以及它使靜態變得不正確或有用的情況。如果某件事是一個常數,靜態可能更有意義。 – 2012-03-13 17:30:04

2

標記爲final的字段並不意味着它是不可變的,只是它的引用不會指向任何其他內存塊。因此,如果一個字段是不可變的,或者它是一個原語,那麼只能使它成爲靜態的。

例如,如果要確保它們永遠不會指向不同的列表對象,但列表本身仍然可以填充數據,清除,再次填充等,通常將列表聲明爲final。當然,聲明這種列表的每個對象並不是強制要在每個實例之間共享它。

private final List<...> list = new ArrayList<...>(); 

最後的關鍵字是爲了防止你犯錯誤,比如設置一個不應該改變的引用爲null。

+0

我覺得你的答案與我的GWT特定問題並無關係。無論如何澄清。 – jabal 2012-03-13 15:41:46