回答
private
- 使其他類可以劫持您記錄static
- 所以只有一個每個類的記錄器實例,也避免試圖序列記錄器final
- 無需改變日誌記錄器
此外,我更喜歡名稱log
儘可能簡單,但描述性。
編輯:但是還有一個有趣的例外規則:
protected final Logger log = LoggerFactory.getLogger(getClass());
,而不是:
private static final Logger log = LoggerFactory.getLogger(Foo.class);
前者的方法可以讓你使用相同的記錄器名稱(實際名稱類)遍歷繼承層次結構中的所有類。因此,如果Bar
延伸Foo
,則兩者都將登錄到Bar
記錄器。有些人覺得更直觀。
什麼時候你想改變字段的值?
如果你永遠不會改變這個值,那麼使得這個字段最終成爲明顯的,你永遠不會改變它的值。
在很多情況下,顯然不添加final這個詞,它就會變成一種垃圾。 – Dima
@Dima:那麼我仍然感激編譯器仍然會拋出一個錯誤,如果我*不小心嘗試在這些情況下嘗試更改值... –
因爲這通常是可以在您的對象的所有實例中共享的那種功能。對於同一類的兩個實例有不同的記錄器沒有太大意義(90%的時間)。
但是,你也可以看到聲明爲單身人士甚至乾脆提供靜態函數來記錄你的東西,有時記錄器類。
通常你初始化記錄器使用類名進行登錄 - 這意味着,如果他們不是一成不變的,你最終會具有它的一個實例(高內存佔用)類的每個實例,但所有這些記錄器將共享相同的配置並且行爲完全相同。這就是static
位背後的原因。此外,因爲每個Logger
被初始化與類名,以防止與子類衝突,聲明它private
所以它不能被繼承。 的final
來自於你不應該在執行過程中改變Logger
點 - 所以一旦初始化你永遠不會「重新配置」它 - 在這種情況下,它是有道理的,使其最終確保無人可換它(通過錯誤或其他方式)。 當然,如果您打算以不同的方式使用Logger
,您可能需要而不是以使用static final
- 但我敢說大概猜測80%的應用程序會使用日誌記錄,如上所述。
static
意味着你只能創建每類中的一個記錄器,每實例類的沒有一個記錄器。一般來說,這就是你想要的 - 因爲伐木者往往只根據班級而變化。
final
表示您不打算更改logger
變量的值。這是真的,因爲你幾乎總是把所有的日誌消息(從一個類)扔到同一個記錄器。即使在極少數情況下,類可能想要將某些消息發送到不同的記錄器,但創建另一個記錄器變量(例如widgetDetailLogger
)會更清晰,而不是通過動態地變更靜態變量的值。
在大多數情況下,您將要更改該值,final
修飾符會將其標記。對於每個類實例,您不需要單獨的實例 - 因此static
。 首先這是爲了性能 - 它可以很好地優化(最終)並保存內存(靜態)。
要回答這個問題,你應該問自己什麼是「靜態」和「最終」。
對於Logger,(我假設你談論Log4J Logger類),你需要每個類的類別。這應該導致只分配一次的事實,並且每個類不需要多個實例。大概沒有理由將一個類的Logger對象暴露給另一個類,爲什麼不把它設爲私有並遵循一些面向對象原則。
另外你應該注意,編譯器能夠從中受益。所以你的代碼執行更好一點:)
檢查此博文:Get Rid of Java Static Loggers。這是你如何使用SLF4J與jcabi-log:
import com.jcabi.log.Logger;
class Foo {
void save(File f) {
Logger.info(this, "file %s saved successfully", f);
}
}
而且從來沒有使用靜態噪聲了。
一個有趣的選擇,絕對清潔。我想知道這與個人班級記錄員相比如何。 – Ross
每次寫更長的記錄器..(this,...)。羅。 –
除了其他答案一兩件事,我跑進是給出的理由是,如果我的記錄既不是靜態的也不是最後:
...
public Logger logger = LoggerFactory.getLogger(DataSummary.class);
public String toJson() {
GsonBuilder gsonBuilder = new GsonBuilder();
return gsonBuilder.create().toJsonTree(this).toString();
}
...
在某些情況下
(我用的是GSON庫)我會得到stackoverflow異常。我的具體情況是實例化包含非靜態非最終記錄器的類。然後調用的toJSON方法,它調用GsonBuilder:
...
DataSummary ds = new DataSummary(data);
System.out.println(ds.toJson());
...
此代碼是脆弱的,但Java7後,我們就可以使用Logger lgr = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
,而不是靜態的記錄。
- 1. 爲什麼我們要聲明一個靜態方法
- 2. 爲什麼我們要在普通類中聲明靜態類?
- 3. 爲什麼變量應聲明爲靜態和最終
- 4. 爲什麼不能在非靜態塊中聲明靜態最終變量?
- 5. 爲什麼我的登錄方法聲明爲靜態?
- 6. 爲什麼WebMethod聲明爲靜態?
- 7. 聲明不能被標記爲「靜態」,爲什麼
- 8. 爲什麼要聲明對最終課程實例的引用是最終的?
- 9. 爲什麼靜態變量需要在C++中聲明兩次
- 10. 應該將GSON聲明爲靜態最終?
- 11. Checkstyle自定義規則確保記錄器被聲明爲靜態最終類屬性
- 12. 爲什麼我不能轉發聲明靜態函數?
- 13. PHP - 爲什麼我無法聲明靜態常量變量?
- 14. 爲什麼我要聲明<PHP
- 15. 爲什麼我們需要的java.sql聲明*包
- 16. 聲明靜態變量時的輸出是什麼?爲什麼?
- 17. 爲什麼聲明的順序對於靜態初始化器很重要?
- 18. 即使函數是靜態的,爲什麼我們不能在函數體內聲明靜態變量?
- 19. 我們爲什麼要在PHP中使用靜態調用?
- 20. 爲什麼我要使用靜態庫?
- 21. 我們真的需要python中的@staticmethod裝飾器聲明靜態方法
- 22. 爲什麼我們可以有靜態最終成員,但不能在內部類中使用靜態方法?
- 23. 應該記錄器總是最終的和靜態的?
- 24. 在公共最終靜態記錄器上禁用Checkstyle警告
- 25. 爲什麼要在C#中聲明靜態類爲密封和抽象?
- 26. 爲什麼要求將全局匿名工會聲明爲靜態?
- 27. 爲什麼.NET委託不能被聲明爲靜態?
- 28. 爲什麼依賴屬性被聲明爲靜態只讀?
- 29. 爲什麼只有靜態字段可以聲明爲'const'?
- 30. 爲什麼jsp中的EL函數必須聲明爲靜態?
+1,答案在修飾符中。 – mre
if static and final then LOG(大寫) – zacheusz
* @ zacheusz *,我知道這就是要點。一些人虔誠地遵循Java命名約定(沒有什麼不妥),但我更願意寫和更愉快的閱讀'log'名稱,而不是用'LOG'分散代碼。只是開發的問題。團隊協議。 –