2011-08-18 38 views
9

在許多類項目的我的工作,我看到一個名爲CLASS_NAME私有靜態最後的成員,這是這樣定義的:是否class.getName()很貴?

public class MyClass { 
    private static final String CLASS_NAME = MyClass.class.getName(); 
    //... 
} 

有什麼好處,如果有的話,這樣做是爲了獲取類的名稱,而不是直接在需要名稱的地方執行MyClass.class.getName()調用?

回答

10

這裏是Class.getName()

public String getName() { 
if (name == null) 
    name = getName0(); 
return name; 
} 

執行正如你可以看到name的值被緩存,所以呼叫不是太昂貴了。它就像常規的getter一樣。無論如何,如果你經常調用它,定義常量可能是一種很好的風格。

1

不,它並不昂貴。我能想到的唯一好處是IDE可以快速向您顯示正在使用此特定常量的位置,而對於長類名稱,常量會更短,使代碼更清晰。

0

我們將不得不看到所有的代碼,看看如何使用CLASS_NAME。但是,很可能在其他地方使用,比如你可以用的Log4J這樣使用它:

// Log4j . Logger --- Get class name in static context by creating an anonymous Throwable and 
// getting the top of its stack-trace. 
// NOTE you must use: getClassName() because getClass() just returns StackTraceElement.class 
static final Logger logger = Logger.getLogger(new Throwable() .getStackTrace()[0].getClassName()); 

它不是一項昂貴的操作,並可能緩存。

6

緩存類名將帶來另一個引用的開銷。這改變了JVM操作碼的成本(CPU複雜度)以適應內存佔用。

現在的CPU速度非常快,基本上都是在內存上等待,所以如果你必須在操作碼和內存佔用之間做出選擇,你最好選擇通過JVM運行更多的操作碼。

起初這似乎並不直觀;但是,請考慮JVM和周圍的硬件。較大的內存佔用空間意味着緩存中最近訪問的項目數量較少,重新獲取超出緩存的項目成本大約是運行單個JVM操作碼成本的1,000到10,000倍。將它與JVM的jit引擎結合起來,大量訪問的代碼塊的CPU複雜性將得到優化(除其他所有內容外)。

所以,一般來說,我會通過不緩存引用來修剪對象,因爲它可以讓更多的對象被推入一級緩存。但是,像所有現實世界的性能調優一樣,您應該測試以確定結果是否與假設相匹配,並且以不會被JVM的所有其他內部工作混淆的方式進行測試。

+0

這是一個很好的建議,謝謝! –

1

這並不昂貴。這似乎是一個用於記錄目的的約定。

比較

logger.entering(CLASS_NAME, ...) 

logger.entering(MyClass.class.getName() ,...) 

除此之外,記錄代碼時複製到另一個來源將不會打破(記錄錯誤的類)。