改善Java程序建議9

建議9:少用靜態(tài)導(dǎo)入

從Java 5開始引入了靜態(tài)導(dǎo)入語(yǔ)法(import static),其目是為了減少字符輸入量,提高代碼的可閱讀性,以便更好地理解程序。我們先來(lái)看一個(gè)不使用靜態(tài)導(dǎo)入的例子,也就是一般導(dǎo)入:

public class MathUtils{
    //計(jì)算圓面積
    public static double calCircleArea(double r){
            return Math.PI * r * r;
    }
    //計(jì)算球面積
    public static double calBallArea(double r){
            return 4* Math.PI * r * r;
    }
}

這是很簡(jiǎn)單的數(shù)學(xué)工具類,我們?cè)谶@兩個(gè)計(jì)算面積的方法中都引入了java.lang.Math類(該類是默認(rèn)導(dǎo)入的)中的PI(圓周率)常量,而Math這個(gè)類寫在這里有點(diǎn)多余,特別是如果MathUtils中的方法比較多時(shí),如果每次都要敲入Math這個(gè)類,繁瑣且多余,靜態(tài)導(dǎo)入可解決此類問(wèn)題,使用靜態(tài)導(dǎo)入后的程序如下:

import static java.lang.Math.PI;
public class MathUtils{
    //計(jì)算圓面積
    public static double calCircleArea(double r){
            return PI * r * r;
    }
    //計(jì)算球面積
    public static double calBallArea(double r){
            return 4 * PI * r * r;
    }
}

靜態(tài)導(dǎo)入的作用是把Math類中的PI常量引入到本類中,這會(huì)使程序更簡(jiǎn)單,更容易閱讀,只要看到PI就知道這是圓周率,不用每次都要把類名寫全了。但是,濫用靜態(tài)導(dǎo)入會(huì)使程序更難閱讀,更難維護(hù)。靜態(tài)導(dǎo)入后,代碼中就不用再寫類名了,但是我們知道類是“一類事物的描述”,缺少了類名的修飾,靜態(tài)屬性和靜態(tài)方法的表象意義可以被無(wú)限放大,這會(huì)讓閱讀者很難弄清楚其屬性或方法代表何意,甚至是哪一個(gè)類的屬性(方法)都要思考一番(當(dāng)然,IDE友好提示功能是另說(shuō)),特別是在一個(gè)類中有多個(gè)靜態(tài)導(dǎo)入語(yǔ)句時(shí),若還使用了*(星號(hào))通配符,把一個(gè)類的所有靜態(tài)元素都導(dǎo)入進(jìn)來(lái)了,那簡(jiǎn)直就是惡夢(mèng)。我們來(lái)看一段例子:

import static java.lang.Double.*;
import static java.lang.Math.*;
import static java.lang.Integer.*;
import static java.text.NumberFormat.*;

public class Client {
  //輸入半徑和精度要求,計(jì)算面積
  public static void main(String[] args) {
            double s = PI * parseDouble(args[0]);
            NumberFormat nf = getInstance();
            nf.setMaximumFractionDigits(parseInt(args[1]));
            formatMessage(nf.format(s));
  }
  //格式化消息輸出
  public static void formatMessage(String s){
            System.out.println("圓面積是:"+s);
  }
}

就這么一段程序,看著就讓人火大:常量PI,這知道,是圓周率;parseDouble方法可能是Double類的一個(gè)轉(zhuǎn)換方法,這看名稱也能猜測(cè)到。那緊接著的getInstance方法是哪個(gè)類的?是Client本地類?不對(duì)呀,沒有這個(gè)方法,哦,原來(lái)是NumberFormate類的方法,這和formateMessage本地方法沒有任何區(qū)別了—這代碼也太難閱讀了,非機(jī)器不可閱讀。
所以,對(duì)于靜態(tài)導(dǎo)入,一定要遵循兩個(gè)規(guī)則:

  • 不使用*(星號(hào))通配符,除非是導(dǎo)入靜態(tài)常量類(只包含常量的類或接口)。
  • 方法名是具有明確、清晰表象意義的工具類。

何為具有明確、清晰表象意義的工具類?我們來(lái)看看JUnit 4中使用的靜態(tài)導(dǎo)入的例子,代碼如下:

import static org.junit.Assert.*;
public class DaoTest {
  @Test
  public void testInsert(){
            //斷言
            assertEquals("foo", "foo");
            assertFalse(Boolean.FALSE);
  }
}

我們從程序中很容易判斷出assertEquals方法是用來(lái)斷言兩個(gè)值是否相等的,assertFalse方法則是斷言表達(dá)式為假,如此確實(shí)減少了代碼量,而且代碼的可讀性也提高了,這也是靜態(tài)導(dǎo)入用到正確地方所帶來(lái)的好處

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容