在聲明一個方法爲 static final 時,IDEA 給出了一個 warning:java
When a static method is overriden in a subclass it can still be accessed via the superclass making the final declaration not very necessary. Declaring a static method final does prevent subclasses from defining a static method with the same signature.
翻譯過來大概是:將一個 static 方法聲明爲 final 不是很是必要的,由於即便聲明爲 final,這個 static 方法在子類中被 override 後,仍然能夠經過父類訪問這個方法。不過被聲明爲 final 確實能夠阻止子類定義一個相同簽名的 static 方法。ide
看來看去我仍是以爲很奇怪,多是由於英語的表達和我中文的思惟不太同樣?...工具
反正 static 真是 Java 的一個很讓人迷惑的 feature =.=this
仍是要好好弄懂它。翻譯
首先,對於 static 方法,咱們知道它是屬於類的,而非對象,能夠認爲 static 方法是沒有 this 隱式參數的,所以可使用類名直接調用 static 方法,一般,在一些工具類中將方法聲明爲 static 使用起來會比較方便。code
固然,經過對象也能夠調用 static 方法,可是並不推薦這麼作,由於一般一個方法被聲明爲 static 有兩種緣由:1. 這個方法不須要訪問對象的狀態 2. 這個方法只須要訪問類的 static 域,因此若是是由於第一個緣由聲明的 static 方法,再用對象調用它時,容易形成混淆,由於這個對象可能和這個 static 方法毫無關係。對象
還有一點就是,static 方法是不能被 override 的get
class SuperClass { public static void staticMethod() { System.out.println("static method in super class"); } } class SubClass extends SuperClass { public static void staticMethod() { System.out.println("static method in sub class"); } public static void main(String[] args) { staticMethod(); } }
這時會發現能夠成功的調用 staticMethod(),而且輸出: static method in sub class,說明調用的是子類中這個方法,那麼爲何說 static 方法是不能被 override 的呢?編譯器
看下面的改動:it
class SubClass extends SuperClass { @Override public static void staticMethod() { System.out.println("static method in sub class"); } public static void main(String[] args) { staticMethod(); } }
當咱們加上 @Override 註釋時就會發現編譯時就報錯了:SubClass.java:2: 錯誤: 方法不會覆蓋或實現超類型的方法,這就說明在子類中的這個 staticMethod 實際上不是對父類方法的 override,而是一個普普統統的子類中的方法,僅此而已。
爲何不能 override static 方法呢?我是這樣理解的,由於 static 是和類關聯的,因此無關對象狀態,而 override 是多態的表現,多態是針對對象而言的,所以 static 方法是不能被 override 的。
這也給咱們提了個醒,想要覆蓋父類方法時最好加上 @Override 註釋,由於它會幫助咱們鑑別是否真的 override 了父類的方法~
下面,若是咱們爲這個方法加上 final 呢?
class SuperClass { public static final void staticMethod() { System.out.println("static method in super class"); } } class SubClass extends SuperClass { //@Override public static void staticMethod() { System.out.println("static method in sub class"); } public static void main(String[] args) { staticMethod(); } }
這時,即便註釋掉 @Override,編譯也會報錯,錯誤信息是:SubClass 中的 staticMethod() 沒法覆蓋 SuperClass 中的 staticMethod(),從這裏就能夠說明 IDEA 給出的那個 warning 的下半句了
Declaring a static method final does prevent subclasses from defining a static method with the same signature.
被聲明爲 final 的 static 方法的確能夠阻止子類定義一個相同簽名的 static 方法。
在 Stack OverFlow 有一個相似的問題
Behaviour of final static method
做者的疑問是,原本 static 方法就是不能被 override 的,爲何在父類中加了 final 修飾符以後編譯器還會報錯。
高票的解釋是
Static methods cannot be overridden but they can be hidden. The ts() method of B is not overriding(not subject to polymorphism) the ts() of A but it will hide it. If you call ts() in B (NOT A.ts() or B.ts() ... just ts()), the one of B will be called and not A. Since this is not subjected to polymorphism, the call ts() in A will never be redirected to the one in B.The keyword final will disable the method from being hidden. So they cannot be hidden and an attempt to do so will result in a compiler error.
大概意思是: static 方法不能被 override 可是能夠被 hide,子類中的 static 方法不是在 override 而是在隱藏,也就是說,若是在子類中直接調用該靜態方法(不是經過類調用),那麼調用的必定是子類本身的那個方法,而不是父類中的,由於子類把父類那個隱藏起來了。而 final 會阻止隱藏,因此在子類中父類的 static 方法 被隱藏 就和 final 的 阻止隱藏 衝突了,所以編譯就會報錯。
因此,自己在父類中聲明爲 static 的方法,在子類中確實不能夠 override,而且子類會隱藏掉父類中的這個 static 方法,讓本身的這個方法和父類的那個同名方法變成兩個無關聯的普通方法。若是在父類中的這個 static 方法加上了 final,那麼子類中就不能夠定義重名的方法了,由於子類的隱藏和 final 的阻止隱藏會發生衝突。
so,我以爲將父類的 static 方法聲明爲 final 仍是有做用的,至少不會讓子類定義一個讓人迷惑的重名方法了嘛,因此最後仍是取消了這個 warning 啦。