摘要:所以,本身在父類中聲明為的方法,在子類中確實(shí)不可以,并且子類會(huì)隱藏掉父類中的這個(gè)方法,讓自己的這個(gè)方法和父類的那個(gè)同名方法變成兩個(gè)無關(guān)聯(lián)的普通方法。
前言
在聲明一個(gè)方法為 static final 時(shí),IDEA 給出了一個(gè) 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.
翻譯過來大概是:將一個(gè) static 方法聲明為 final 不是非常必要的,因?yàn)榧词孤暶鳛?final,這個(gè) static 方法在子類中被 override 后,仍然可以通過父類訪問這個(gè)方法。不過被聲明為 final 確實(shí)可以阻止子類定義一個(gè)相同簽名的 static 方法。
看來看去我還是覺得很奇怪,可能是因?yàn)橛⒄Z的表達(dá)和我中文的思維不太一樣?...
反正 static 真是 Java 的一個(gè)很讓人迷惑的 feature =.=
還是要好好弄懂它。
static final 方法首先,對(duì)于 static 方法,我們知道它是屬于類的,而非對(duì)象,可以認(rèn)為 static 方法是沒有 this 隱式參數(shù)的,因此可以使用類名直接調(diào)用 static 方法,通常,在一些工具類中將方法聲明為 static 使用起來會(huì)比較方便。
當(dāng)然,通過對(duì)象也可以調(diào)用 static 方法,但是并不推薦這么做,因?yàn)橥ǔR粋€(gè)方法被聲明為 static 有兩種原因:1. 這個(gè)方法不需要訪問對(duì)象的狀態(tài) 2. 這個(gè)方法只需要訪問類的 static 域,所以如果是因?yàn)榈谝粋€(gè)原因聲明的 static 方法,再用對(duì)象調(diào)用它時(shí),容易造成混淆,因?yàn)檫@個(gè)對(duì)象可能和這個(gè) static 方法毫無關(guān)系。
還有一點(diǎn)就是,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(); } }
這時(shí)會(huì)發(fā)現(xiàn)可以成功的調(diào)用 staticMethod(),并且輸出: static method in sub class,說明調(diào)用的是子類中這個(gè)方法,那么為什么說 static 方法是不能被 override 的呢?
看下面的改動(dòng):
class SubClass extends SuperClass { @Override public static void staticMethod() { System.out.println("static method in sub class"); } public static void main(String[] args) { staticMethod(); } }
當(dāng)我們加上 @Override 注釋時(shí)就會(huì)發(fā)現(xiàn)編譯時(shí)就報(bào)錯(cuò)了:SubClass.java:2: 錯(cuò)誤: 方法不會(huì)覆蓋或?qū)崿F(xiàn)超類型的方法,這就說明在子類中的這個(gè) staticMethod 實(shí)際上不是對(duì)父類方法的 override,而是一個(gè)普普通通的子類中的方法,僅此而已。
為什么不能 override static 方法呢?我是這樣理解的,因?yàn)?static 是和類關(guān)聯(lián)的,所以無關(guān)對(duì)象狀態(tài),而 override 是多態(tài)的表現(xiàn),多態(tài)是針對(duì)對(duì)象而言的,因此 static 方法是不能被 override 的。
這也給我們提了個(gè)醒,想要覆蓋父類方法時(shí)最好加上 @Override 注釋,因?yàn)樗鼤?huì)幫助我們鑒別是否真的 override 了父類的方法~
下面,如果我們?yōu)檫@個(gè)方法加上 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(); } }
這時(shí),即使注釋掉 @Override,編譯也會(huì)報(bào)錯(cuò),錯(cuò)誤信息是:SubClass 中的 staticMethod() 無法覆蓋 SuperClass 中的 staticMethod(),從這里就可以說明 IDEA 給出的那個(gè) warning 的下半句了
Declaring a static method final does prevent subclasses from defining a static method with the same signature.
被聲明為 final 的 static 方法的確可以阻止子類定義一個(gè)相同簽名的 static 方法。
在 Stack OverFlow 有一個(gè)類似的問題
Behaviour of final static method
作者的疑問是,本來 static 方法就是不能被 override 的,為什么在父類中加了 final 修飾符之后編譯器還會(huì)報(bào)錯(cuò)。
高票的解釋是
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 而是在隱藏,也就是說,如果在子類中直接調(diào)用該靜態(tài)方法(不是通過類調(diào)用),那么調(diào)用的一定是子類自己的那個(gè)方法,而不是父類中的,因?yàn)樽宇惏迅割惸莻€(gè)隱藏起來了。而 final 會(huì)阻止隱藏,所以在子類中父類的 static 方法 被隱藏 就和 final 的 阻止隱藏 沖突了,因此編譯就會(huì)報(bào)錯(cuò)。
所以,本身在父類中聲明為 static 的方法,在子類中確實(shí)不可以 override,并且子類會(huì)隱藏掉父類中的這個(gè) static 方法,讓自己的這個(gè)方法和父類的那個(gè)同名方法變成兩個(gè)無關(guān)聯(lián)的普通方法。如果在父類中的這個(gè) static 方法加上了 final,那么子類中就不可以定義重名的方法了,因?yàn)樽宇惖碾[藏和 final 的阻止隱藏會(huì)發(fā)生沖突。
so,我覺得將父類的 static 方法聲明為 final 還是有作用的,至少不會(huì)讓子類定義一個(gè)讓人迷惑的重名方法了嘛,所以最后還是取消了這個(gè) warning 啦。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/69714.html
摘要:反匯編器與反編譯器不同,反編譯器的目標(biāo)是高級(jí)語言而非匯編語言。反匯編器的反匯編輸出通常格式化為適合人類閱讀,而非用作匯編器的輸入源,因此它主要是一個(gè)逆向工程工具。本文章參考了通過命令分析匯編指令反匯編器 問題描述 寫這篇文章是為了記錄我這幾天遇到的一個(gè)疑惑,并且順藤摸瓜的學(xué)習(xí)一下javap命令。遇到的疑惑是這樣的:我在看使用枚舉類型實(shí)現(xiàn)單列模式的博客時(shí),發(fā)現(xiàn)一些博客中寫到的枚舉類型的反...
摘要:應(yīng)用在修飾類名,類成員,方法,參數(shù),構(gòu)造器中。接口修飾符構(gòu)造器修飾符方法修飾符字段修飾符參數(shù)修飾符最基本的修飾符作用在類上當(dāng)此修飾符修飾類。作用在構(gòu)造器上在構(gòu)造器上,只允許使用三種修飾符,。當(dāng)此修飾符修飾構(gòu)造器。 1、什么是修飾符? 指的是一種標(biāo)識(shí)類型以及類型成員的訪問范圍的聲明。 應(yīng)用在修飾類名,類成員,方法,參數(shù),構(gòu)造器中。 2、修飾符的有幾種? ...
摘要:鎖與很好的隔離使用者與實(shí)現(xiàn)者所需要關(guān)注的領(lǐng)域。那么這個(gè)就是包裝線程并且放入到隊(duì)列的過程實(shí)現(xiàn)的方法。也證實(shí)了就是獲取鎖的線程的節(jié)點(diǎn)。如果發(fā)生異常取消請求,也就是將當(dāng)前節(jié)點(diǎn)重隊(duì)列中移除。 前言 自從JDK1.5后,jdk新增一個(gè)并發(fā)工具包java.util.concurrent,提供了一系列的并發(fā)工具類。而今天我們需要學(xué)習(xí)的是java.util.concurrent.lock也就是它下面的...
摘要:前言繼續(xù)前一章,接下來解析標(biāo)簽的的屬性信息及的注冊。不過只不過是一個(gè)子類的實(shí)現(xiàn),而大部分屬性都是保存到了中去了。也就是函數(shù)中的代碼的解析了。通過注冊對(duì)于的注冊,或許很多人認(rèn)為的方式就是將直接放入中就好了,使用作為。 前言:繼續(xù)前一章,接下來解析Bean標(biāo)簽的的屬性信息及bean的注冊。 1. 解析當(dāng)前bean標(biāo)簽的內(nèi)容 當(dāng)我們創(chuàng)建了bean信息的承載實(shí)例之后, 便可以進(jìn)行bean信息的...
摘要:前言昨天看了一篇關(guān)于用幾行代碼實(shí)現(xiàn)框架的博客,收獲很大,于是我想在這篇博客的基礎(chǔ)上理一理思路,盡可能的多加一點(diǎn)注釋,進(jìn)一步降低學(xué)習(xí)框架原理的門檻。 前言 昨天看了一篇關(guān)于用幾行代碼實(shí)現(xiàn)RPC框架的博客[http://javatar.iteye.com/blog...](),收獲很大,于是我想在這篇博客的基礎(chǔ)上理一理思路,盡可能的多加一點(diǎn)注釋,進(jìn)一步降低學(xué)習(xí)RPC框架原理的門檻。 原理圖...
閱讀 3156·2021-10-08 10:04
閱讀 1098·2021-09-30 09:48
閱讀 3466·2021-09-22 10:53
閱讀 1684·2021-09-10 11:22
閱讀 1698·2021-09-06 15:00
閱讀 2156·2019-08-30 15:56
閱讀 719·2019-08-30 15:53
閱讀 2288·2019-08-30 13:04