摘要:所以,本身在父類中聲明為的方法,在子類中確實不可以,并且子類會隱藏掉父類中的這個方法,讓自己的這個方法和父類的那個同名方法變成兩個無關聯的普通方法。
前言
在聲明一個方法為 static final 時,IDEA 給出了一個 warning:
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 方法。
看來看去我還是覺得很奇怪,可能是因為英語的表達和我中文的思維不太一樣?...
反正 static 真是 Java 的一個很讓人迷惑的 feature =.=
還是要好好弄懂它。
static final 方法首先,對于 static 方法,我們知道它是屬于類的,而非對象,可以認為 static 方法是沒有 this 隱式參數的,因此可以使用類名直接調用 static 方法,通常,在一些工具類中將方法聲明為 static 使用起來會比較方便。
當然,通過對象也可以調用 static 方法,但是并不推薦這么做,因為通常一個方法被聲明為 static 有兩種原因:1. 這個方法不需要訪問對象的狀態 2. 這個方法只需要訪問類的 static 域,所以如果是因為第一個原因聲明的 static 方法,再用對象調用它時,容易造成混淆,因為這個對象可能和這個 static 方法毫無關系。
還有一點就是,static 方法是不能被 override 的
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 的呢?
看下面的改動:
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 啦。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/69714.html
摘要:反匯編器與反編譯器不同,反編譯器的目標是高級語言而非匯編語言。反匯編器的反匯編輸出通常格式化為適合人類閱讀,而非用作匯編器的輸入源,因此它主要是一個逆向工程工具。本文章參考了通過命令分析匯編指令反匯編器 問題描述 寫這篇文章是為了記錄我這幾天遇到的一個疑惑,并且順藤摸瓜的學習一下javap命令。遇到的疑惑是這樣的:我在看使用枚舉類型實現單列模式的博客時,發現一些博客中寫到的枚舉類型的反...
摘要:應用在修飾類名,類成員,方法,參數,構造器中。接口修飾符構造器修飾符方法修飾符字段修飾符參數修飾符最基本的修飾符作用在類上當此修飾符修飾類。作用在構造器上在構造器上,只允許使用三種修飾符,。當此修飾符修飾構造器。 1、什么是修飾符? 指的是一種標識類型以及類型成員的訪問范圍的聲明。 應用在修飾類名,類成員,方法,參數,構造器中。 2、修飾符的有幾種? ...
摘要:鎖與很好的隔離使用者與實現者所需要關注的領域。那么這個就是包裝線程并且放入到隊列的過程實現的方法。也證實了就是獲取鎖的線程的節點。如果發生異常取消請求,也就是將當前節點重隊列中移除。 前言 自從JDK1.5后,jdk新增一個并發工具包java.util.concurrent,提供了一系列的并發工具類。而今天我們需要學習的是java.util.concurrent.lock也就是它下面的...
摘要:前言繼續前一章,接下來解析標簽的的屬性信息及的注冊。不過只不過是一個子類的實現,而大部分屬性都是保存到了中去了。也就是函數中的代碼的解析了。通過注冊對于的注冊,或許很多人認為的方式就是將直接放入中就好了,使用作為。 前言:繼續前一章,接下來解析Bean標簽的的屬性信息及bean的注冊。 1. 解析當前bean標簽的內容 當我們創建了bean信息的承載實例之后, 便可以進行bean信息的...
摘要:前言昨天看了一篇關于用幾行代碼實現框架的博客,收獲很大,于是我想在這篇博客的基礎上理一理思路,盡可能的多加一點注釋,進一步降低學習框架原理的門檻。 前言 昨天看了一篇關于用幾行代碼實現RPC框架的博客[http://javatar.iteye.com/blog...](),收獲很大,于是我想在這篇博客的基礎上理一理思路,盡可能的多加一點注釋,進一步降低學習RPC框架原理的門檻。 原理圖...
閱讀 3142·2021-10-08 10:04
閱讀 1080·2021-09-30 09:48
閱讀 3449·2021-09-22 10:53
閱讀 1664·2021-09-10 11:22
閱讀 1682·2021-09-06 15:00
閱讀 2142·2019-08-30 15:56
閱讀 704·2019-08-30 15:53
閱讀 2273·2019-08-30 13:04