Java Coding Style:static final Logger 的命名問題
簡述
最近公司要求使用PMD做靜態程式碼檢查時
private static final Logger logger = LoggerFactory.getLogger(Example.class);
此類程式碼會提示以下錯誤
A variable naming conventions rule - customize this to your liking. Currently, it checks for final variables that should be fully capitalized and non-final variables that should not include underscores.
分析
這裡應該是預設使用 static final 修飾的 Logger 物件是常量,所以要求使用大寫。
實際上並非如此,Java 與 C++ 不同,沒有專門的關鍵字 const
用來定義常量。Java 常量使用 static final 修飾,但是用 static final 修飾的並不一定是常量。
The sole exception to the previous rule concerns “constant fields,” whose names should consist of one or more uppercase words separated by the underscore character, for example, VALUES or NEGATIVE_INFINITY. A constant field is a static final field whose value is immutable. If a static final field has a primitive type or an immutable reference type(Item 15), then it is a constant field.
For example, enum constants are constant fields. If a static final field has a mutable reference type, it can still be a constant field if the referenced object is immutable.
—— Effective Java
Names of fields being used as constants should be all upper-case, with underscores separating words. The following are considered to be constants:
- All static final primitive types (Remember that all interface fields are inherently static final).
- All static final object reference types that are never followed by “.” (dot).
- All static final arrays that are never followed by “[” (dot).
—— Achut Reddy - Java Coding Style Guide
用 final 修飾的變數只能賦值一次,但是這個值對於引用型別來說,只是一個引用地址,引用地址不變並不意味著其狀態不可變(如,成員變數可變),所以一個引用型別若要作為常量還需要是不可變的(immutable )。
結論
結合 Java 常量的實現方式,Sun 的程式設計規範,slf4j 的示例等,此處使用小寫完全沒有問題。
參考
1.SLF4J FAQ : Should Logger members of a class be declared as static ?
2.Logging-FrequentlyAskedQuestions : Should I declare Log references static or not?
3.Should a -static final Logger- be declared in UPPER-CASE- - Stack Overflow
4.Why is there no Constant feature in Java - Stack Overflow
5.Logger (SLF4J 1.8.0-beta2 API)