你真正的了解過JAVA import 導(dǎo)包嗎?

前言

歡迎大家來到院長的博客,記錄一下工作中的瑣事。本文主要內(nèi)容白話(說一下)import 導(dǎo)入 應(yīng)不應(yīng)該加上static關(guān)鍵字。

時間,今天下午。同事最近在做代碼優(yōu)化,準(zhǔn)備將代碼合并到Dev分支。我耳朵比較敏銳聽到了,也想了解一下他優(yōu)化了什么內(nèi)容。于是上gitlab上看了一圈,發(fā)現(xiàn)代碼中貌似有一些不妥的地方,并針對import static 導(dǎo)入方式做了一下面對面討論。

下面將我個人想法和建議做一下梳理。希望能幫助到有需要的同學(xué)。如果哪里說的不對,歡迎大家指出。

假裝是個動圖.png

代碼展示

下面代碼,模擬一下今天下午的真實場景。XXXUtil代碼中大約有20多個常量類 都是采用如下靜態(tài)import導(dǎo)入的形式。

import static com.package.framework.cmd.Constants.LOGINSUCCESS;
import static com.package.framework.cmd.Constants.LOGINFAIL;
import static com.package.framework.cmd.Constants.LOGINCANCEL;
import static com.package.framework.cmd.Constants.N;
import static com.package.framework.cmd.Constants.N;
import static com.package.framework.cmd.Constants.N;
import static com.package.framework.cmd.Constants.N;
import static com.package.framework.cmd.Constants.N;
import static com.package.framework.cmd.Constants.;

public class XXXUtil {//類名
      switch (cmd) {
       case LOGINSUCCESS:
        //執(zhí)行具體的邏輯
         break;
      }
}

下列展示的是我認(rèn)為這樣寫比較好的代碼,不需要大量靜態(tài)導(dǎo)入,同樣達(dá)到一樣的效果,直觀清晰明了。雖然從編譯結(jié)果、業(yè)務(wù)邏輯角度來說,上面寫的代碼你也不能說錯或者有問題。但是總感覺很別扭,通過接下來說明和小例子。來闡述我得觀點。


public class XXXXXUtil {//類名
      switch (cmd) {
       case  Constants.LOGINSUCCESS:
        //執(zhí)行具體的邏輯
         break;
      }
}


JAVA 知識了解

在 Java 中,靜態(tài)導(dǎo)入的概念在 1.5 版本中引入。借助靜態(tài)導(dǎo)入,我們可以直接訪問類的靜態(tài)成員,無需類名或任何對象。例如:我們可以通過使用 Math 類即Math.sqrt()來使用 Math 類的 sqrt() 方法,但是通過使用靜態(tài)導(dǎo)入,我們可以直接訪問 sqrt() 方法。

據(jù)SUN公司稱,靜態(tài)導(dǎo)入將提高代碼可讀性并增強(qiáng)編碼。但是一些編程大佬們不認(rèn)可這樣的說法,認(rèn)為它會導(dǎo)致程序混亂并且不利于編程。給到的建議是:如果沒有特殊要求,盡量不要使用靜態(tài)導(dǎo)入。為什么呢?文末會給出答案。

正常improt 導(dǎo)入

class HelloWorld{
    public static void main(String[] args){
        System.out.println(Math.sqrt(4));
        System.out.println(Math.pow(2, 2));
        System.out.println(Math.abs(6.3));
    }
}

輸出:

2.0

4.0

6.3


靜態(tài)導(dǎo)入

靜態(tài)導(dǎo)入的方式,可以觀察到下面的代碼省略了Math。輸出的結(jié)果也是一致的

import static java.lang.Math.*;

public class HelloWorld{
    public static void main(String[] args){
        System.out.println(sqrt(4));
        System.out.println(pow(2, 2));
        System.out.println(abs(6.3));
    }
}

輸出:

2.0

4.0

6.3

靜態(tài)導(dǎo)入升級版

靜態(tài)導(dǎo)入的方式,可以觀察到下面的代碼省略了Math和System。輸出的結(jié)果也是一致的

import static java.lang.Math.*;
import static java.lang.System.*;
public class HelloWorld{
    public static void main(String[] args){
        out.println(sqrt(4));
        out.println(pow(2, 2));
        out.println(abs(6.3));
    }
}

輸出:

2.0

4.0

6.3

注意: System 是 java.lang 包中的一個類,out 是 System 類中的靜態(tài)變量。通過靜態(tài)導(dǎo)入的方式,我們可以不用類名去調(diào)用它。

靜態(tài)導(dǎo)入帶來的歧義點:
如果從多個不同的類中導(dǎo)入兩個同名的靜態(tài)成員,編譯器會拋出錯誤,因為在沒有類名限定的情況下,它將無法確定使用哪個成員。 代碼和錯誤截圖如下所示。

import static java.lang.Integer.*;
import static java.lang.Byte.*;
public class HelloWorld{
    public static void main(String[] args){
        out.println(MAX_VALUE);
    }
}

錯誤輸出.png

Error:Reference to MAX_VALUE is ambigious //錯誤:對 MAX_VALUE 的引用不明確

說明:在上面的代碼中,我們試圖訪問 MAX_VALUE 變量,但是每個原始數(shù)據(jù)類型都包含 MAX_VALUE 變量,該變量在 Wrapper 類中預(yù)先聲明。這里我們同時導(dǎo)入 Integer 和 Byte 類并嘗試訪問靜態(tài)變量 MAX_VALUE。

但編譯器會因為看到兩個導(dǎo)入語句而感到懵逼,因為 Integer 和 Byte 類都包含一個靜態(tài)變量 MAX_VALUE。因此這里編譯器拋出一個錯誤,說Reference to MAX_VALUE is ambiguous。

正常import 導(dǎo)入和靜態(tài)import 導(dǎo)入的區(qū)別

在正常import 導(dǎo)包中,我們能夠訪問任何包中存在的類和接口。但是使用靜態(tài)導(dǎo)入,我們可以直接訪問類的所有靜態(tài)成員(變量和方法),而無需顯式調(diào)用類名。

靜態(tài)導(dǎo)入的優(yōu)缺點:

  • 靜態(tài)導(dǎo)入的優(yōu)點:如果經(jīng)常訪問類的任何靜態(tài)成員,則需要較少的代碼。

  • 靜態(tài)導(dǎo)入的缺點:過度使用靜態(tài)導(dǎo)入功能,它會使程序不可讀和不可維護(hù)。

    • 假如同時導(dǎo)入的兩個類中又有重命名的靜態(tài)成員,會出現(xiàn)報錯。例如Integer類和Long類的MAX_VALUE。

總結(jié):兩個包中包含兩個同名的類/接口是非常少見的。因此,正常導(dǎo)入我們很少會出現(xiàn)問題(歧義)。但是有可能兩個類包含相同的變量,所以在靜態(tài)導(dǎo)入會出現(xiàn)引用不明確報錯。這就是為什么上面提到,如果沒有這樣特殊要求不建議使用靜態(tài)引用的原因。

結(jié)尾

有用的知識又增加了,如果文本對你有幫助,希望給個關(guān)注和點贊。你的支持是我繼續(xù)寫作的動力。(瘋狂暗示 ?。。。?/p>

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容